__unsafe_unratained 修饰符的变量
- 使用__unsafe_unretained 使用的对象 必须保证对象必须存在否则会报错
- 使用__weak修饰的对象。当没有强引用执行它的时候 会自动赋值为nil
编译器会检查方法名是否以alloc/new/copy/mutableCopy开始,如果不是则自动将返回值注册到autoreleasePool中
+(id)array{ id obj = [[NSMutableArray alloc]init]; return obj }
因为没有显示指定所有权修饰符,所以id obj同附有__strong修饰符的 id __strong obj 是完全一样的,由于return 使得对象变量超出其作用域,所以强引用对自己的持有者会被自动释放,但是该对象作为函数的返回值,编译器会自动将其注册到autoreleasePool当中。
使用__weak 修饰符的变量时,实际上必定要访问注册到autoreleasePool中的对象。 因为__weak 只能持有对象的弱引用,而在访问引用对象的过程中,该对象可能已经被废弃掉了。如果吧要访问的对象注册到autoreleasepool当中,那么在@autorelease释放之前,可以确保该对象一直存在。 因此使用__weak修饰符修饰的变量,就必定要使用注册到autoreleasepool中的对象
id的指针或者对象的指针,在没有显示指定时会被附加上__autorealeasing 修饰符
__strong修饰的id变量被初始化为nil,但是无法保证__strong 修饰的id*类型 被初始化为nil
id __strong obj = [[NSObject alloc]init];
上述代码的模拟代码
id objc = objc_msgSend(NSObject,@selector(alloc))
objc_msgSend(obj,@selector())
id __strong obj = [NSMutableArray array]
上述代码本质执行 objc_msgSend(NSMutableArray,@selector(array)); objc_retainAutoreleasedReturnValue(objc) obj_release(obj)
__weak 被赋值为nil的过程
- 从weak表中获取废弃对象的地址作为键值的记录
- 将包含在记录种的所有附有 __weak修饰符变量的地址赋值为nil
- 从weak表中删除该记录
- 从引用计数表中删除废弃对象的地址作为键值的记录
使用用__weak修饰符的变量,即是使用注册到autoreleasePool中的对象