1.3.5 属性
assign __unsafe_unretained
copy __strong(强引用对象的副本)
strong __strong
retain __strong
weak __weak
一个类的成员变量和属性是同一类型
时,修饰符必须一致
1.3.6 数组
静态数组超出其作用域时,数组中各个附有 __strong 修饰符的变量失效,其强引用消失,所赋值的对象随之释放。
编译器能够根据静态数组中的变量的作用域自动插入释放赋值对象的代码,而在动态数组中,编译器不能确定数组的生存周期,所以无从处理。所以一定要将 nil 赋值给所有元素,使所有元素所赋值对象的强引用失效,从而释放那些对象。
1.3 完
1.4 ARC 实现
1.4.1 __strong 修饰符
本章讲 __strong 修饰符在程序中是如何运行的。
id __strong obj = [[NSObject alloc] init];
编译器的模拟代码如下
id obj = objc_msgSend(NSObject, @selecor(alloc));
objc_msgSend(obj, @selector(init));
调用两次 objc_msgSend 方法,然后编译器自动插入 objc_release 方法。然后对比其他获取强引用的方法
id __strong obj = [NSMutableArray array];
编译器模拟代码
id obj = objc_msgSend(NSMutalbleArray, @selector(array));
objc_retainedAutoreleasedReturnedValue(obj);
objc_release(obj)
这个过程中调用了 objc_retainedAutoreleasedReturnedValue 方法,这个方法主要用于最优化程序。这个方法一般和 objc_autoreleasedReturnedValue 方法成对出现。
+ (id) array {
return [[NSObject alloc] init];
}
以下是模拟代码
+ (id) array {
id obj = objc_msgSend(NSMutableArray, @selector(alloc));
objc_msgSend(obj, @selector(init));
return objc_autoreleaseReturndValue(obj);
}
objc_autoreleaseReturndValue方法执行后会检查调用方的执行命令列表,如果有 objc_retainedAutoreleasedReturnedValue 方法则会绕过 autoreleasepool 直接返回生成的对象
1.4.2 __weak 修饰符
__weak 的功能
a. 若附有 __weak 修饰符的变量所以用的对象废弃,则将 nil 赋值给该变量。
b. 使用附有 __weak 修饰符的变量,即是使用注册到 autoreleasepool 中的对象。
__weak a功能的实现
{
id __weak obj1 = obj;
}
模拟代码{
id obj1;
objc_initWeak(&obj1, obj);
objc_destroyWeak(&obj1);
}
objc_initWeak 和 objc_destroyWeak 方法实际上是调用 objc_storeWeak 方法,上面的模拟代码可以转换为
{
id obj1;
obj1 = 0;
objc_store(&obj1, obj);
objc_store(&obj1, 0);
}
objc_store(&obj1, obj) 将 obj 的地址当做 key 第一参数即 weak 变量的地址注册到 weak 表中,当第二参数为0时将 weak 变量地址从 weak表中移除。
由于一个对象可以被多个weak变量引用,所以,weak表中一个对象可以注册多个 weak 变量的地址。当对象废弃时会首先从 weak 表中获取引用记录,然后逐一赋值nil,过后从 weak 表中删除该记录,最后在引用计数表中删除以废弃对象为键值的记录
__weak b功能的实现
{
id __weak obj1 = obj;
NSLog(@“%@”, obj1);
}
模拟代码
id obj1;
objc_initWeak(&obj1, obj);
id temp = objc_loadWeakRetained(&obj1)
objc_autorelease(tmp);
NSLog(@“%@”, tmp);
objc_destroyWeak(&obj1);
1.4.3 __autorelease 修饰符
略
1.4.4 retainCount
略