美文网首页
iOS的dealloc方法做了什么工作?weak指针为什么会自动

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

作者: Bauyin89 | 来源:发表于2018-09-10 12:07 被阅读23次

    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);
    }
    

    相关文章

      网友评论

          本文标题:iOS的dealloc方法做了什么工作?weak指针为什么会自动

          本文链接:https://www.haomeiwen.com/subject/awqsgftx.html