__weak修饰符
1.若有__weak修饰符变量所引用的对象被废弃,将nil赋值给该变量。
2.使用__weak修饰符的变量,即是使用注册到autoreleasepool中的对象。
将__weak修饰符的obj1赋值给__strong修饰符的obj
{
id __strong obj = [[NSObject alloc]init];
id __weak obj1 = obj;
}
由于苹果不让看到内部实现,模拟编译器的代码
id obj1
objc_initWeak(&obj1,obj);
objc_destroyWeak(&obj1);
通过objc_initWeak
函数初始化附有__weak修饰符的变量,在变量作用域结束时调用objc_destroyWeak
函数释放该变量。
如以下源码所示,objc_initWeak
函数将附有__weak修饰符的变量初始化为0后,会将赋值的对象作为参数调用objc_storeWeak
函数
obj1 = 0;
objc_storeWeak(&obj1, obj);
/*objc_destroyWeak函数将0作为参数调用objc_storeWeak函数*/、、
objc_storeWeak(&obj1, 0);
objc_storeWeak
函数把第二个参数的赋值对象的地址作为键值,将第一参数的附有__weak修饰符的变量的地址注册到weak表中,如果第二个参数为0,则把变量的地址从weak表中删除。
weak表
与引用计数表相同,作为散列表被实现,如果使用weak
表,将废弃对象的地址作为键值进行检索,就能高度地获取对应的附有__weak修饰符
的变量的地址,另外,由于一个对象可同时赋值给多个附有__weak修饰符
的变量中,对于一个键值,可注册多个变量的地址。
对象通过objc_release
函数释放
1.
objc_release
2.因为引用计数为0所有执行dealloc
3._objc_rootDealloc
4.object_dispose
5.objc_destructInstance
6.objc_clear_deallocating
对于废弃时最后调用objc_clear_deallocating
函数的动作如下:
1.从weak表中获取废弃对象的内存地址为键值的记录
2.将包含在记录中所有附有__weak修复的变量地址,赋值为nil
3.从weak表中删除记录
4.从引用计数表中删除废除对象的地址为键值的记录
由此可知,如果大量使用附有__weak修饰符的变量,则会消耗相应的cpu资源,良策只在需要避免玄幻引用时使用__weak修饰符
网友评论