美文网首页
iOS--dealloc

iOS--dealloc

作者: mayuee | 来源:发表于2022-09-16 01:27 被阅读0次
    1. dealloc
    - (void)dealloc {
        _objc_rootDealloc(self);
    }
    
    1. _objc_rootDealloc()
    _objc_rootDealloc(id obj)
    {
        ASSERT(obj);
    
        obj->rootDealloc();
    }
    
    1. obj->rootDealloc()
    objc_object::rootDealloc()
    {
          //isTaggedPointer 类型  直接返回
        if (isTaggedPointer()) return;  // fixme necessary?
    
        if (fastpath(isa.nonpointer  &&  
                     !isa.weakly_referenced  &&       //弱引用
                     !isa.has_assoc  &&                    //关联对象
                     !isa.has_cxx_dtor  &&                //C++
                     !isa.has_sidetable_rc))               //散列表(引用计数表)
        {
            assert(!sidetable_present());
            free(this);
        } 
        else {
            object_dispose((id)this);
        }
    }
    
    1. object_dispose((id)this);
    id object_dispose(id obj)
    {
        if (!obj) return nil;
    
        objc_destructInstance(obj);    
        free(obj);
    
        return nil;
    }
    
    1. objc_destructInstance(obj)
    /***********************************************************************
    * objc_destructInstance
    * Destroys an instance without freeing memory. 
    * Calls C++ destructors.
    * Calls ARC ivar cleanup.
    * Removes associative references.
    * Returns `obj`. Does nothing if `obj` is nil.
    **********************************************************************/
    void *objc_destructInstance(id obj) 
    {
        if (obj) {
            // Read all of the flags at once for performance.
            bool cxx = obj->hasCxxDtor();
            bool assoc = obj->hasAssociatedObjects();
    
            // This order is important.
            if (cxx) object_cxxDestruct(obj);                     //C++
            if (assoc) _object_remove_assocations(obj);         //移除关联对象
            obj->clearDeallocating();
        }
    
        return obj;
    }
    
    1. object_cxxDestruct
    /***********************************************************************
    * object_cxxDestruct.
    * Call C++ destructors on obj, if any.
    * Uses methodListLock and cacheUpdateLock. The caller must hold neither.
    **********************************************************************/
    void object_cxxDestruct(id obj)
    {
        if (!obj) return;
        if (obj->isTaggedPointer()) return;
        object_cxxDestructFromClass(obj, obj->ISA());
    }
    
    1. _object_remove_assocations
    void
    _object_remove_assocations(id object)
    {
        ObjectAssociationMap refs{};
    
        {
            AssociationsManager manager;
            AssociationsHashMap &associations(manager.get());
            AssociationsHashMap::iterator i = associations.find((objc_object *)object);
            if (i != associations.end()) {
                refs.swap(i->second);
                associations.erase(i);
            }
        }
    
        // release everything (outside of the lock).
        for (auto &i: refs) {
            i.second.releaseHeldValue();
        }
    }
    
    1. clearDeallocating()
    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());
    }
    
    1. sidetable_clearDeallocating()
    void 
    objc_object::sidetable_clearDeallocating()
    {
        SideTable& table = SideTables()[this];
    
        // clear any weak table items
        // clear extra retain count and deallocating bit
        // (fixme warn or abort if extra retain count == 0 ?)
        table.lock();
        RefcountMap::iterator it = table.refcnts.find(this);
        if (it != table.refcnts.end()) {
            if (it->second & SIDE_TABLE_WEAKLY_REFERENCED) {
                weak_clear_no_lock(&table.weak_table, (id)this);
            }
            table.refcnts.erase(it);
        }
        table.unlock();
    }
    
    1. clearDeallocating_slow
    // Slow path of clearDeallocating() 
    // for objects with nonpointer isa
    // that were ever weakly referenced 
    // or whose retain count ever overflowed to the side table.
    NEVER_INLINE void
    objc_object::clearDeallocating_slow()
    {
        ASSERT(isa.nonpointer  &&  (isa.weakly_referenced || isa.has_sidetable_rc));
    
        SideTable& table = SideTables()[this];
        table.lock();
        if (isa.weakly_referenced) {
            weak_clear_no_lock(&table.weak_table, (id)this);
        }
        if (isa.has_sidetable_rc) {
            table.refcnts.erase(this);
        }
        table.unlock();
    }
    
    

    相关文章

      网友评论

          本文标题:iOS--dealloc

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