美文网首页
iOS日记4-weak关键字

iOS日记4-weak关键字

作者: Mcyboy007 | 来源:发表于2017-02-09 19:15 被阅读0次

1.runtime中如何实现weak

  • 生成weak对象
{
  //obj是__strong修饰且被赋值的对象
  id __weak obj1 = obj;
}

//编译器的模拟代码
//转化1
id obj1;
objc_initWeak(&obj1, obj);
objc_destroyWeak(&obj1);  //作用域结束,释放对象

//转化2
id obj1;
obj1 = 0;
objc_storeWeak(&obj1, obj);
objc_storeWeak(&obj1, 0);

weak对象有一张weak表(类似引用计数表),是作为散列表被实现。赋值对象(obj)的内存地址作为key,weak对象(obj1)的内存地址作为value存储。一个objc可以赋值给多个weak对象,所以一个key可以对应多个value。

  • 释放weak对象

(1) objc_release
(2) 引用计数为0,执行dealloc
(3) _objc_rootDealloc
(4) object_dispose
(5) objc_destructInstance
(6) objc_clear_deallocating

主要讲一下第(6)步,它做的事情有:
1)从weak表中获取weak对象的地址为键值的记录
2)将包含在记录中所有附有__weak修饰符变量的地址,赋值为nil
3)从weak表中删除该记录
4)从引用计数表中删除weak对象的地址为键值的记录

2.__weak对象与autoreleasepool的关系

__weak修饰符的变量,会注册到autoreleasepool中
{
  //obj是__strong修饰且被赋值的对象
  id __weak obj1 = obj;
  NSLog(@"%@", obj1);
}

//编译器的模拟代码
id obj1;
objc_initWeak(&obj1, obj);
id tmp = objc_loadWeakRetained(&obj1);
objc_autorelease(tmp);
NSLog(@"%@", obj1);
objc_destroyWeak(&obj1);  //作用域结束,释放对象

objc_loadWeakRetained函数取出附有__weak修饰符变量所引用的对象,并retain
objc_autorelease函数将对象注册到autoreleasepool中

所以,如果大量使用附有weak修饰符的变量,注册到autoreleasepool的对象也会大量增加。解决办法:最好先暂时将weak对象赋值给strong修饰符的变量后再使用

相关文章

网友评论

      本文标题:iOS日记4-weak关键字

      本文链接:https://www.haomeiwen.com/subject/wdliittx.html