美文网首页
-(void)dealloc底层执行了什么?

-(void)dealloc底层执行了什么?

作者: 牛奶红茶 | 来源:发表于2021-03-30 16:20 被阅读0次

    直接从源码中查找,我们在NSObject.mm中可以查到dealloc函数

    - (void)dealloc {
        _objc_rootDealloc(self);
    }

    进入_objc_rootDealloc函数

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

    继续进入 rootDealloc

    inline void
    objc_object::rootDealloc()
    {
        if (isTaggedPointer()) return;  // fixme necessary? 首先判断对象是不是isTaggedPointer,如果是isTaggedPointer那么没有采用引用计数计数,直接return
    //不是TaggedPointer,就去销毁这个对象object_dispose
        if (fastpath(isa.nonpointer  &&  
                     !isa.weakly_referenced  &&  
                     !isa.has_assoc  &&  
                     !isa.has_cxx_dtor  &&  
                     !isa.has_sidetable_rc))
        {
            assert(!sidetable_present());
            free(this);
        }
        else {
            object_dispose((id)this);
        }
    }

    nonpointer              是否优化过isa指针

     weakly_reference  是否存在弱引用指向

     has_assoc              是否设置过关联对象

     has_cxx_dtor         是否有cpp的析构函数(.cxx_destruct)

     has_sidetable_rc   引用计数器是否过大无法存储在isa中

    如果存在是上面的任意一种,将会调用object_dispose()方法,做下一步处理

    如果不存在上面的任何一种情夸昂,则可以执行释放操作,C函数的free()

    执行object_dispose()方法

    id
    object_dispose(id obj)
    {
        if (!obj) return nil;

        objc_destructInstance(obj);  //销毁实例 
        free(obj);//释放对象

        return nil;
    }

    执行objc_destructInstance()销毁实例

    void *objc_destructInstance(id obj)
    {
        if (obj) {
            // Read all of the flags at once for performance.
            bool cxx = obj->hasCxxDtor(); //1.是否有析构函数
            bool assoc = obj->hasAssociatedObjects();//2.是否有关联对象

            // This order is important.
            if (cxx) object_cxxDestruct(obj);//3.有就释放(清除成员变量)
            if (assoc) _object_remove_assocations(obj);//4.移除当前对象的管理啊安对象
            obj->clearDeallocating();//5.将指向当前对象的弱指针置为nil
           }

        return obj;
    }

    将指向当前对象的弱指针置为nil

    本质是:

    ->1.如果是优化过的ISA,先取出SideTable拿到弱引用表(散列表,也称之为hash表)和当前对象

    ->2.执行weak_clear_no_lock函数

    ->3.以当前对象的地址为key通过hash_pointer()函数返回值&散列表的mask 

    size_t begin = hash_pointer(new_entry->referent) & (weak_table->mask); 值那拿到对应索引取出相关的weak_entry进行移除操作

    ->4.判断isa.has_sidetable_rc(引用计数表)中还有数据,会把引用计数表中的引用计数擦除掉table.refcnts.erase()

    执行clearDeallocating() 将指向当前对象的弱引用指针置为nil

    inline void
    objc_object::clearDeallocating()
    {
        if (slowpath(!isa.nonpointer)) {
            // Slow path for raw pointer isa.
            sidetable_clearDeallocating();
        }
        else if (slowpath(isa.weakly_referenced  ||  isa.has_sidetable_rc)) {
            // Slow path for non-pointer isa with weak refs and/or side table data.
            clearDeallocating_slow();
        }

        assert(!sidetable_present());
    }

    相关文章

      网友评论

          本文标题:-(void)dealloc底层执行了什么?

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