Autorelease的疑问

先看一下下面两段代码分别输出结果是什么:

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了。 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值