七、weak置空原理
当面试官问你weak置空原理是什么,你可能只知道weak怎么用却不知道怎么答吧
在weak一行打下断点运行项目
int main(int argc, const char * argv[]) {
@autoreleasepool {
FXPerson *person = [[FXPerson alloc] init];
id __weak person = object;
}
return 0;
}
Xcode菜单栏Debug->Debug Workflow->Always show Disassembly打上勾查看汇编——汇编代码会来到libobjc库的objc_initWeak

1.weak创建过程
①objc_initWeak
-
location:表示__weak指针的地址(我们研究的就是__weak指针指向的内容怎么置为nil) -
newObj:所引用的对象,即例子中的person
id
objc_initWeak(id *location, id newObj)
{
if (!newObj) {
*location = nil;
return nil;
}
return storeWeak<DontHaveOld, DoHaveNew, DoCrashIfDeallocating>
(location, (objc_object*)newObj);
}
②storeWeak
-
HaveOld:weak指针之前是否已经指向了一个弱引用 -
HaveNew:weak指针是否需要指向一个新引用 -
CrashIfDeallocating:如果被弱引用的对象正在析构,此时再弱引用该对象,是否应该crash
storeWeak最主要的两个逻辑点(源码太长,这里不贴了)

由于是第一次调用,所以走
haveNew分支——获取到的是新的散列表SideTable,主要执行了weak_register_no_lock方法来进行插入
③weak_register_no_lock
- 主要进行了
isTaggedPointer和deallocating条件判断 - 将被弱引用对象所在的
weak_table中的weak_entry_t哈希数组中取出对应的weak_entry_t - 如果
weak_entry_t不存在,则会新建一个并插入 - 如果存在就将指向被弱引用对象地址的指针
referrer通过函数append_referrer插入到对应的weak_entry_t引用数组

④append_referrer
找到弱引用对象的对应的weak_entry哈希数组中插入

2.weak创建流程

3.weak销毁过程
由于弱引用在析构dealloc时自动置空,所以查看dealloc的底层实现并LLVM调试
-
_objc_rootDealloc->rootDealloc -
rootDealloc->object_dispose -
object_dispose->objc_destructInstance -
objc_destructInstance->clearDeallocating -
clearDeallocating->sidetable_clearDeallocating -
sidetable_clearDeallocating3->table.refcnts.erase(it)
4.weak销毁流程
(非本人做图)具体可查阅iOS底层学习 - 内存管理之weak原理探究
