OC_自动引用计数器_0x02

0x01.alloc/retain/release/dealloc实现

alloc:

struct obj_layout {

  NSUInteger retained;

};

+ (id)alloc

{

  int size = sizeof(struct obj_layout) + 对象大小;

  struct obj_layout *p = (struct obj_layout *)calloc(1, size);

  return (id)(p+1);

)

  alloc类方法用struct obj_layout中的retained整数来保存引用计数,并将其写入对象内存头部,该对象内存块全部置0后返回。

  执行alloc后对象的retainCount是“1”,下面通过GNUstep的源代码来确认:

  -(NSUInteger)retainCount

  {

    return NSExtraRefCount(self) + 1;

  }

  inline NSUInteger

  NSExtraRefCount(id anObject)

  {

    return ((struct obj_layout *) anObject)[-1].retained;

  }

  由对象寻址找到对象内存头部,从而访问其中的retained变量。因为分配时全部置0,所以retained为0.由NSExtraRefCount(self) + 1得出,retainCount为1可以推测出,retain方法使retained变量加1,

  而release方法使retained变量减1.

  下面来看一下调用出的retain实例方法。

  -(id)retain

  {

    NSIncrementExtraRefCount(self);

    return self;

  }

  inline void

  NSIncrementExtraRefCount(id anObject)

  {

    if(((struct obj_layout *)anObject [-1].retained == UINT_MAX -1)

    {

      [NSException raise:NSInternalInconsistencyException format:@"NSIncrementExtraRefCount() asked to increment too far");

    }

    ((struct obj_layout *)anObject)[-1].retained++;

  }

  

原文地址:https://www.cnblogs.com/fkunlam/p/4903672.html