dealloc实现原理

当对象引用计数为0时,运行时会调用_objc_rootDealloc,实现如下:

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

 

_objc_rootDealloc(id obj)
{
    assert(obj);

    obj->rootDealloc();
}

 

inline void
objc_object::rootDealloc()
{
    if (isTaggedPointer()) return;  // fixme necessary?

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

isTaggedPointer 小标记指针直接返回,不用释放
对象采用了优化的isa计数方式(isa.nonpointer)
对象没有被weak引用!isa.weakly_referenced
没有关联对象!isa.has_assoc
没有自定义的C++析构方法!isa.has_cxx_dtor
没有用到sideTable来做引用计数 !isa.has_sidetable_rc

如果满足以上条件 则可直接调用free释放内存,否则会调用object_dispose函数

id 
object_dispose(id obj)
{
    if (!obj) return nil;
    // 析构obj
    objc_destructInstance(obj);
    // 释放内存
    free(obj);

    return nil;
}

 

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

        // 如果有c++析构函数 则调用c++析构函数.
        if (cxx)
            object_cxxDestruct(obj);

        // 如果有关联对象则移除关联对象
        if (assoc)
            _object_remove_assocations(obj);
        // 清理引用计数以及弱引用
        obj->clearDeallocating();
    }

    return obj;
}

至此对象相关的cxx虚函数、关联对象、弱引用全部释放完毕

 
posted @ 2022-05-07 11:46  黄增松  阅读(128)  评论(0编辑  收藏  举报