0%

__autoreleasing 的理解

__autoreleasing 修饰符

将对象赋值给附有 __autoreleasing 修饰符的变量等同于 ARC 无效时调用对象的 autorelease 方法。我们通过以下源代码来看一下

1
2
3
@autoreleasepool {
id __autoreleasing obj = [[NSObject alloc] init];
}

该源代码主要将 NSObject 类对象注册到 autoreleasepool 中,可作如下变换:

1
2
3
4
5
6
/* 编译器的模拟代码 */
id pool = objc_autoreleasePoolPush();
id obj = objc_msgSend(NSObject, @selector(alloc));
objc_msgSend(obj, @selector(init));
objc_autorelease(obj);
objc_autoreleasePoolPop(pool);

这与苹果的 autorelease 实现中的说明(参考 1.2.7 节)完全相同。虽然 ARC 有效和无效时,其在源代码上的表现有所不同,但 autorelease 的功能完全一样。

在 alloc/new/copy/mutableCopy 方法群之外的方法中使用注册到 autoreleasepool 中的对象会如何呢?下面我们来看看 NSMutableArray 类的 array 类方法。

1
2
3
@autoreleasepool {
id __autoreleasing obj = [NSMutableArray array];
}

这与前面的源代码有何不同呢?

1
2
3
4
5
6
/* 编译器的模拟代码 */
id pool = objc_autoreleasePoolPush();
id obj = objc_msgSend(NSMutableArray, @selector(array));
objc_retainAutoreleasedReturnValue(obj);
objc_autorelease(obj);
objc_autoreleasePoolPop(pool);

虽然持有对象的方法从 alloc 方法变为 objc_retainAutoreleasedReturnValue 函数, 但注册 autoreleasepool 的方法没有改变,仍是 objc_autorelease 函数。

备注:欢迎转载,但请一定注明出处! http://blog.wangruofeng007.com