Autorelease的疑问

来源:互联网 发布:淘宝卖家开通直播条件 编辑:程序博客网 时间:2024/05/01 18:21
先看一下下面两段代码分别输出结果是什么:

1  ARC 环境下: 

NSObject *obj = [[NSObject alloc] init];id __autoreleasing o = obj;NSLog(@"ARC:%d", _objc_rootRetainCount(obj)); 

2  MRC环境下:

NSObject *obj = [[NSObject alloc] init];[obj  autorelease];NSLog(@"MRC:%d", obj .retainCount); 

结果:

ARC:2
MRC:1

这里产生几个疑问:

Autoreleasepool里的对象不是用数组存的么?

2 为什么add到Autoreleasepool的对象引用计数没有发生变化?

3 ARC下为什么是2,而MRC下是1?

针对前两个问题, 查了一下资料《Pro.Multithreading.and.Memory.Management.for.iOS.and.OS.X》:

当你在mrc下调用 [obj  autorelease];时,NSObject的autorelease方法的GNUstep实现是这样的:

- (id) autorelease {     [NSAutoreleasePool addObject:self]; }- (void) addObject: (id)anObj {     [array addObject:anObj]; }

当然具体实现也是有优化的。

Apple的实现是这样的:
在AutoreleasePoolPage这个类里,

(可以看这里—》http://opensource.apple.com/source/objc4/objc4-493.11/runtime/objc-arr.mm

static inline id autorelease(id obj) {     /* It corresponds to NSAutoreleasePool class method addObject. */     AutoreleasePoolPage *autoreleasePoolPage = /* getting active AutoreleasePoolPage object */     autoreleasePoolPage->add(obj); }
id* add(id obj) {     assert(!full());     unprotect();     *next++ = obj;     protect();     return next-1; }

        我们可以看到实际上只是做了一个add操作,GNUstep addObject里的array实际上使用link list去实现的,而apple用的是一个动态数组,从上面的add方法的实现可以看出只有指针操作, 所以不会对引用计数造成影响。

         第3个问题在arc下引用计数发生变化 是这一句id __autoreleasing o = obj;导致的。
这个可以参见这里:http://clang.llvm.org/docs/AutomaticReferenceCounting.html#ownership.semantics
其中有这样的描述:
For __autoreleasing objects, the new pointer is retained, autoreleased, and stored into the lvalue using primitive semantics.
也就是说上面的代码在arc下,编译器做转化的时候实际上会转化为:
id o = [obj retain] autorelease];

所以引用计数就变成2了。 



0 0
原创粉丝点击