iOS的dealloc方法做了什么工作?weak指针为什么会自动

2018-09-10  本文已影响23人  Bauyin89

Dealloc方法底层流程如下:

//[NSObject dealloc]
- (void)dealloc
{
    _objc_rootDealloc(self);
}

_objc_rootDealloc(id obj)
{
    obj->rootDealloc();
}

inline void objc_object::rootDealloc()
{
    if (isTaggedPointer()) return;  // fixme necessary?
    
    //isa使用了TaggedPoint,且没有weak引用,没有关联对象,没有使用析构函数,没有使用引用计数表
    if (fastpath(isa.nonpointer  &&
                 !isa.weakly_referenced  &&
                 !isa.has_assoc  &&
                 !isa.has_cxx_dtor  &&
                 !isa.has_sidetable_rc))
    {
        free(this);//释放内存
    }
    else
    {
        object_dispose((id)this);
    }
}

id object_dispose(id obj)
{
    objc_destructInstance(obj);//销毁对象
    free(obj);//释放内存
    return nil;
}

void *objc_destructInstance(id obj)
{
    object_cxxDestruct(obj);//调用对象的析构函数
    _object_remove_assocations(obj);//去除关联对象
    clearDeallocating();//清理残余信息
}

void clearDeallocating()
{
    if (!isa.nonpointer)//isa没有优化
    {
        sidetable_clearDeallocating();//清理sidetable
    }
    else
    {
        clearDeallocating_slow();//清理残余信息
    }
}

void sidetable_clearDeallocating()
{
    SideTable.lock();
    
    weak_clear_no_lock(&SideTable.weak_table, (id)this);//清理弱引用表
    SideTable.refcnts.erase(it);//清理引用计数表
    
    SideTable.unlock();
}

void clearDeallocating_slow()
{
    SideTable.lock();

    weak_clear_no_lock(&SideTable.weak_table, (id)this);//清理弱引用表
    SideTable.refcnts.erase(this);//清理引用计数表
    
    SideTable.unlock();
}

void weak_clear_no_lock(weak_table_t *weak_table, id referent_id)
{
    weak_entry_t *entry = weak_entry_for_referent(weak_table, referent_id);
    weak_referrer_t *referrers = entry->referrers;
    size_t count = TABLE_SIZE(entry);

    for (size_t i = 0; i < count; ++i)
    {
        objc_object **referrer = referrers[i];
        *referrer = nil;

    }
    
    weak_entry_remove(weak_table, entry);
}
上一篇下一篇

猜你喜欢

热点阅读