weak关键字的作用是弱引用,所引用对象的计数不会增加,并在引用对象释放的时候自动被置为nil
weak是有runtime维护的Weak表
weak表
weak_table_t是一个全局weak引用的表,使用不定类型对象的地址作为key,用weak_entry_t类型结构体作为value
weak_table_tweak_entry_t是存储在弱引用表中的一个内部结构体,它负责维护和存储指向一个对象的所有弱引用hash表,其定义如下:
weak_entry_t总之,
weak_table_t(weak全局表):采用hash的方式把所有weak引用的对象,存储所有引用weak对象
weak_entry_t(weak_table_t表中hash表的value值,weak对象体),用于记录hash表中的weak对象
weak释放为nil的过程
weak释放为nil,需要对整个释放过程了解,如下是释放的整理流程
1、调用objc_release
2、因为对象的引用计数为0,所以执行dealloc
3、在dealloc中调用_objc_rootDealloc函数
4、在_objc_rootDealloc函数中调用object_dispose函数
5、调用objc_destructInstance
6、最后调用_objc_clear_deallocating
对象准备释放时,调用clearDeallocating函数,clearDeallocating首选根据对象地址获取所有weak指针地址的数组,然后遍历这个数组将其中的数据置为nil,最后把entry从weak表中删除,最后清理对象的记录
objc_clear_deallocating工作步骤:
1、根据对象地址获取所有weak指针
2、将数组中所有weak修饰符变量的地址,赋值为nil
3、从weak表中删除该记录
4、从引用计数表中删除废弃对象地址为键值的记录
其实Weak表是一个hash(哈希)表,然后里面的key是指向对象的地址,Value是Weak指针的地址的数组。
weak与assign的区别
1、weak只可以修饰对象,assign除了可修饰对象外,还可以修饰基本数据类型
2、weak不会产生野指针,assign修饰对象可能产生野指针,如果修饰基本数据类型则不会产生野指针(因为值类型会被放入到栈中,遵循先进后出,有系统负责管理栈内存。而引用类型则会被放入到堆中需要自己手动管理内存)
3、assign适合修饰基本数据类型,如int、float、struct...,不适用于引用类型
weak适合修饰delegate,block等引用类型,不会导致野指针,不会导致循环引用,非常安全
网友评论