runtime源码探究(一) weak的实现

本文探讨了Objective-C runtime中weak引用的建立和销毁过程。在对象初始化时,通过objc_initWeak函数和storeWeak函数实现弱引用,利用SideTable结构存储weak_entry_t,确保不增加对象引用计数。当对象销毁时,通过objc_clear_deallocating函数清除所有weak指针,防止悬挂引用。此外,解释了weak引用在autoreleasepool中的行为,系统会通过objc_loadWeakRetained和objc_autorelease确保其在池中的有效性。
摘要由CSDN通过智能技术生成

weak指针的建立

weak修饰对象不增加其引用计数,apple通过一个hash表来实现对象的弱引用。
在Xcode下编写如下代码:

__weak obj1 = obj;

编译器编译之后变成类似如下的代码:

objc_initWeak(&obj1,obj);

翻开runtime源码,NSObject.mm,找到objc_initWeak函数,实现如下:

 * @param location Address of __weak ptr. 
 * @param newObj Object ptr. 
 */
id
objc_initWeak(id *location, id newObj)
{
    if (!newObj) {
        *location = nil;
        return nil;
    }

    return storeWeak<false/*old*/, true/*new*/, true/*crash*/>(location, (objc_object*)newObj);
}

apple对参数已有说明,location是weak指针的地址,newObj是被指向的对象的地址。接下来寻找storeWeak函数,先看apple对storeWeak函数的注释:

// Update a weak variable.
// If HaveOld is true, the variable has an existing value
// that needs to be cleaned up. This value might be nil.
// If HaveNew is true, there is a new value that needs to be
// assigned into the variable. This value might be nil.
// If CrashIfDeallocating is true, the process is halted if newObj is
// deallocating or newObj’s class does not support weak references.
// If CrashIfDeallocating is false, nil is stored instead.

如果weak指针有指向的对象,那么清除这个对象,然后weak指针指向新的对象;如果weak指针指向新的对象,那么就将新的weak引用存起来;如果weak指针指向的对象被释放了,那么就不会存储这个weak引用,直接返回nil。下面一行行看代码:

template <bool HaveOld, bool HaveNew, bool CrashIfDeallocating>
static id 
storeWeak(id *location, objc_object *newObj)
{
    assert(HaveOld  ||  HaveNew);
    if (!HaveNew) assert(newObj == nil);

    Class previouslyInitializedClass = nil;
    id oldObj;
    SideTable *oldTable;
    SideTable *newTable;

    // Acquire locks for old and new values.
    // Order by lock address to prevent lock ordering problems. 
    // Retry if the old value changes underneath us.
 retry:
    if (HaveOld) {
        oldObj = *location;
        oldTable &
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值