1、ARC的实现原理
我们都知道,ARC是编译器特性,程序在编译的时候,编译器帮我们在合适的地方插入retain、release等代码以管理对象的引用计数,从而达到自动管理对象生命周期的目的。
但是只有编译器是无法单独完成这一工作的,还需要OC运行时库的配合协助,因此ARC的实现工具主要包括:
- LLVM编译器(clang 3.0以上)
- OC运行时库493.9以上
2、__strong修饰符
使用 __strong 修饰变量的程序究竟是如何运行的
{
id __strong object = [[NSObject alloc] init];
}
转换后的模拟源代码为
/*编译器的模拟代码*/
id object = objc_msgSend(NSObjct,@selector(alloc));
objc_msgSend(object,@selector(init));
objc_release(object);
对象变量生成时,alloc和init分别进行了方法调用,对象变量作用域结束时调用objc_release方法释放对象变量,虽然ARC情况下不能使用release方法,但是由此可见编译器编译时在合适的地方插入了release。
在使用alloc、new、copy、mutableCopy以外的方法生成对象变量方法时会有什么不同
{
id __strong object = [NSMutableArray array];
}
调用array的类方法转换后如下
{
/*编译器的模拟代码*/
id object = objc_msgSend(NSMutableArray,@selector(array));
objc_retainAutoreleasedReturnValue(object);
objc_release(object);
}
中间的objc_retainAutoreleasedReturnValue(object)函数与之前的不同,它主要是起何作用的呢?
objc_retainAutoreleasedReturnValue(object)函数的作用:最优化程序运行
自己持有(retain)对象的函数,但它持有的应为返回注册在autoreleasepool中对象的方法或函数的返回值。
objc_retainAutoreleasedReturnValue函数与objc_autoreleasedReturnValue是成对出现的,现在看看NSMutableArray类的array类方法的编译器实现
+ (id)array {
return [[NSMutableArray alloc] init];
}
转换后的源代码
+ (id)array {
/*编译器的模拟代码*/
id obj = objc_msgSend(NSMutableArray,@selector(alloc));
objc_msgSend(obj,@selector(init));
return objc_autoreleaseReturnValue(obj);
}
通过objc_autoreleaseReturnValue函数将对象注册在自动释放池autoreleasepool中并返回,但是与objc_autorelease函数不同的是,objc_autoreleaseReturnValue函数一般不仅限于注册对象到autoreleasepool中去。
objc_autoreleaseReturnValue与objc_retainAutoreleasedReturnValue的配合使用,可以不将对象注册到autoreleasepool中而直接传递,达到最优化
objc_autoreleaseReturnValue函数会检查使用该函数的方法或者函数的调用方的执行命令列表,如果调用方在调用该函数或方法之后,紧接着调用了objc_retainAutoreleasedReturnValue函数,那么将不再将对象注册到autoreleasepool中去,而直接将对象传递给调用方。
相比于objc_retain函数来说objc_retainAutoreleasedReturnValue函数在返回一个即使没有注册到autoreleasepool中的对象,也能正确的获取对象。