__weak 修饰符
__weak修饰符: 1 使用__weak修饰符所引用的对象被释放,则相应的该对象被设置为nil。
2 使用__weak修饰符的对象,即相当于使用注册到autoreleasepool中的对象。
1 __weak修饰符实现原理( iOS很多功能都是runtime实现的__weak也不例外,runtime实现了weak属性)
取个例子: {
id obj = [ [NSobject alloc] init];
id __weak objWeak = obj;
// obj = nil; ARC下方法执行完的某一时刻会执行 [obj release]
}
上面的 objWeak 是__weak 修饰符对象,objWeak会被注册到用于存放weak 变量的hash表中,key值为obj的地址, 如果obj 引用计数为0的时候,则把obj的地址从weak表中删除。使用obj 对象地址做为key进行检索,获取对应的objWeak的地址。
另外由于一个对象可以同时赋值给多个__weak对象,所以对一个key,可以注册多个变量的地址。
注意:__weak 修饰符如果大量使用则会消耗相应的CPU资源。所以最好只在为了避免循环引用时候使用__weak修饰符。
2 建议不要使用__weak修饰符的情况
id __weak obj = [ [NSobject alloc] init];
NSLog (@"%@",obj);
输出结果:(null)
原因是没有对创建出来的对象持有者,内存直接被释放了。
3 如果大量使用附有__weak修饰符的变量,注册到autoreleasepool 中的对象也会大量增加,因此使用__weak修饰符时,最好先暂时赋值给附有__strong修饰符的变量后再使用。
建议:
id obj = [[NSObject alloc]init];
id __weak obj1 = obj;
id tmp = obj1;
NSLog(@"obj = %@",tmp);
NSLog(@"obj = %@",tmp);
NSLog(@"obj = %@",tmp);
NSLog(@"obj = %@",tmp);
不建议:
id obj = [[NSObject alloc]init];
id __weak obj1 = obj;
NSLog(@"obj = %@",obj1);
NSLog(@"obj = %@",obj1);
NSLog(@"obj = %@",obj1);
NSLog(@"obj = %@",obj1);
4 allowsWeakReference /retainWeakReference 方法返回值是NO 情况不建议使用
本文内容粗略,有什么错误理解不到位的,希望有大神指点。谢谢。(文中的理解多是看书和大牛博客得来的,在此略做总结)
浙公网安备 33010602011771号