iOS weak关键字
作为一个面试经常被问到的问题,iOS weak关键字
基本概念
在iOS中,weak的常用来处理NSTimer,delegate,block的循环引用问题。它是一个弱引用,在对象释放之后,weak指针自动指向nil,避免野指针,避免错误的内存访问。
如何在对象释放的时候指针置为nil
还记得,第一次,接触到这个问题,只知道weak是弱引用,对象释放以后,指针会自动赋值为nil。但是为什么在对象释放后,指针就成了nil,中间进行了什么样的操作。
weak说的简单一些,其实就相当于一个哈希表,在runtime中,是一个觉weak表的东西。将所指对象的地址作为key,vaule是所有指针地址的一个数组,因为一个对象,可以有多个weak指针指向它。
在对象释放的时候,会调用一个函数,我们可以看到关键的一些代码
for(size_t i = 0; i < count; ++i) {
objc_object **referrer = referrers[i];
if(referrer) {
if(*referrer == referent) {
*referrer = nil;
}
elseif(*referrer) {
_objc_inform("__weak variable at %p holds %p instead of %p. "
"This is probably incorrect use of "
"objc_storeWeak() and objc_loadWeak(). "
"Break on objc_weak_error to debug.\n",
referrer, (void*)*referrer, (void*)referent);
objc_weak_error();
}
}
}
weak_entry_remove(weak_table, entry);
这里只截取了少量的代码,可以看到,在对象释放的时候,会通过key找到weak表中的vaule,从这个数组中,依次把指针设为nil,最后,把weak表相关的记录也全部删除。
weak 表实现原理
weak 的实现原理可以概括一下三步:
1、初始化时:runtime会调用objc_initWeak函数,初始化一个新的weak指针指向对象的地址。
2、添加引用时:objc_initWeak函数会调用 objc_storeWeak() 函数, objc_storeWeak() 的作用是更新指针指向,创建对应的弱引用表。
3、释放时,调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取所有weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个entry从weak表中删除,最后清理对象的记录。