(三)并不很深入地探究 arc中 __autoreleassi
2017-10-06 本文已影响21人
madaoCN
关联文章
(一)并不很深入地探究 arc中 __strong 修饰符
(二)并不很深入地探究 arc中 __weak 修饰符
(三)并不很深入地探究 arc中 __autoreleassing 修饰符
ARC是由编译器和运行时系统进行内存管理,本文将从编译器和runtime系统出发,探究 __autoreleassing 修饰符的实现过程。
在此之前我们需要知道如何获取汇编输出(便于理解,下文汇编输出将整理成伪代码)
使用alloc/new/copy/mutableCopy 等自己生成并持有的情况
将对象赋值给带有__autoreleasing修饰符的变量等同于ARC无效时调用autorelease方法,例如:
@autoreleasepool {
id __autoreleasing obj = [[NSObject alloc] init];
}
汇编输出:
id pool = objc_autoreleasePoolPush()
id obj = objc_msgSend(NSObject, @selector(alloc));
objc_msgSend(obj, @selector(init));
objc_autorelease(obj);
objc_autoreleasePoolPop(pool)
objc_autorelease
源码
#if __OBJC2__
__attribute__((aligned(16)))
id
objc_autorelease(id obj)
{
if (!obj) return obj;
if (obj->isTaggedPointer()) return obj;
return obj->autorelease();
}
// OBJC2
#else
// not OBJC2
id objc_autorelease(id obj) { return [obj autorelease]; }
清晰明了objc_autorelease
,最终调用对象的autorelease
方法
使用alloc/new/copy/mutableCopy 等以外持有非自己生成对象情况
@autoreleasepool {
id __autoreleasing obj = [NSArray array];
}
汇编输出:
id pool = objc_autoreleasePoolPush()
id obj = objc_msgSend(NSArray, @selector(array));
objc_retainAutoreleasedReturnValue(obj);
objc_autorelease(obj);
objc_autoreleasePoolPop(pool)
与前面源码有何不同呢?只有多调用了一个方法objc_retainAutoreleasedReturnValue
, (另一篇文章 (一)并不很深入地探究 arc中 __strong 修饰符 已经详解过该方法源码,此处不赘述 )简而言之就是持有注册到autoreleaspool中的对象 ,也就是将持有的方法从alloc
变为了objc_retainAutoreleasedReturnValue
,其余仍然没有改变,仍然调用了objc_autorelease
函数