IOS 拾遗程序员iOS进阶之路

(三)并不很深入地探究 arc中 __autoreleassi

2017-10-06  本文已影响21人  madaoCN

关联文章

(一)并不很深入地探究 arc中 __strong 修饰符
(二)并不很深入地探究 arc中 __weak 修饰符
(三)并不很深入地探究 arc中 __autoreleassing 修饰符

ARC是由编译器和运行时系统进行内存管理,本文将从编译器和runtime系统出发,探究 __autoreleassing 修饰符的实现过程。

在此之前我们需要知道如何获取汇编输出(便于理解,下文汇编输出将整理成伪代码)

iOS 获取汇编输出方法

使用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函数

上一篇下一篇

猜你喜欢

热点阅读