android智能指針介紹

本篇介紹

android中有三種智能指針,分別是輕量級(jí)指針,強(qiáng)指針,弱指針。輕量級(jí)指針實(shí)現(xiàn)簡(jiǎn)潔,效果類似于強(qiáng)指針,然后強(qiáng)指針和弱指針的實(shí)現(xiàn)比較復(fù)雜比較重一些。本篇就介紹下這三種指針的具體實(shí)現(xiàn)。

輕量級(jí)指針

輕量級(jí)指針在Android中是由LightRefBase來(lái)提供的,看下內(nèi)容:

template <class T>
class LightRefBase
{
public:
    inline LightRefBase() : mCount(0) { }
    inline void incStrong(__attribute__((unused)) const void* id) const {
        mCount.fetch_add(1, std::memory_order_relaxed);
    }
    inline void incStrongRequireStrong(__attribute__((unused)) const void* id) const {
        if (0 == mCount.fetch_add(1, std::memory_order_relaxed)) {
            LightRefBase_reportIncStrongRequireStrongFailed(this);
        }
    }
    inline void decStrong(__attribute__((unused)) const void* id) const {
        if (mCount.fetch_sub(1, std::memory_order_release) == 1) {
            std::atomic_thread_fence(std::memory_order_acquire);
            delete static_cast<const T*>(this);
        }
    }
    //! DEBUGGING ONLY: Get current strong ref count.
    inline int32_t getStrongCount() const {
        return mCount.load(std::memory_order_relaxed);
    }

protected:
    inline ~LightRefBase() { }

private:
    friend class ReferenceMover;
    inline static void renameRefs(size_t /*n*/, const ReferenceRenamer& /*renamer*/) { }
    inline static void renameRefId(T* /*ref*/, const void* /*old_id*/ , const void* /*new_id*/) { }

private:
    mutable std::atomic<int32_t> mCount;
};

一個(gè)類只要繼承LightRefBase,然后配合sp就可以使用智能指針的功能了。sp后面會(huì)單獨(dú)介紹。
從這兒可以看出來(lái),輕量級(jí)指針主要是在類里面添加了一個(gè)原子變量作為計(jì)數(shù)變量,然后通過(guò)incStrong和decStrong來(lái)實(shí)現(xiàn)計(jì)數(shù)的增減。
這兒有一個(gè)細(xì)節(jié)是這個(gè)計(jì)數(shù)可能會(huì)在多個(gè)線程里面訪問(wèn),因此就會(huì)出現(xiàn)并發(fā)問(wèn)題。比如一個(gè)對(duì)象對(duì)應(yīng)的多個(gè)智能指針在多個(gè)線程里面使用,這時(shí)候就需要某個(gè)機(jī)制可以保證計(jì)數(shù)的準(zhǔn)確。具體的策略就在incStrong和decStong里面,可以看到主要是使用了原子操作,并指定了內(nèi)存序。這樣通過(guò)內(nèi)存屏障手段實(shí)現(xiàn)了不用持鎖也能實(shí)現(xiàn)一致性。
接下來(lái)看下sp,一個(gè)類繼承了LightRefBase后就擁有了智能指針計(jì)數(shù)機(jī)制,然后通過(guò)sp來(lái)操作指針才能實(shí)現(xiàn)智能管理內(nèi)存的效果:

template<typename T>
class sp {
public:
    inline sp() : m_ptr(0) { }

    sp(T* other);  // NOLINT(implicit)
    sp(const sp<T>& other);
    sp(sp<T>&& other);
    template<typename U> sp(U* other);  // NOLINT(implicit)
    template<typename U> sp(const sp<U>& other);  // NOLINT(implicit)
    template<typename U> sp(sp<U>&& other);  // NOLINT(implicit)

    ~sp();

    // Assignment

    sp& operator = (T* other);
    sp& operator = (const sp<T>& other);
    sp& operator = (sp<T>&& other);

    template<typename U> sp& operator = (const sp<U>& other);
    template<typename U> sp& operator = (sp<U>&& other);
    template<typename U> sp& operator = (U* other);

    //! Special optimization for use by ProcessState (and nobody else).
    void force_set(T* other);

    // Reset

    void clear();

    // Accessors

    inline T&       operator* () const     { return *m_ptr; }
    inline T*       operator-> () const    { return m_ptr;  }
    inline T*       get() const            { return m_ptr; }
    inline explicit operator bool () const { return m_ptr != nullptr; }

    // Operators

    COMPARE(==)
    COMPARE(!=)
    COMPARE(>)
    COMPARE(<)
    COMPARE(<=)
    COMPARE(>=)

private:    
    template<typename Y> friend class sp;
    template<typename Y> friend class wp;
    void set_pointer(T* ptr);
    T* m_ptr;
};

可以看到sp定義了對(duì)指針的基本操作,并通過(guò)m_ptr保存所管理的對(duì)象指針,看下構(gòu)造和析構(gòu)方法:

template<typename T>
sp<T>::sp(T* other)
        : m_ptr(other) {
    if (other)
        other->incStrong(this);
}

初始化m_ptr,然后調(diào)用incStrong增加計(jì)數(shù),其實(shí)就是調(diào)用LightRefBase的incStrong,再看下移動(dòng)拷貝構(gòu)造函數(shù):

template<typename T>
sp<T>::sp(sp<T>&& other)
        : m_ptr(other.m_ptr) {
    other.m_ptr = nullptr;
}

移動(dòng)只涉及擁有權(quán)的轉(zhuǎn)移,因此不能更新計(jì)數(shù)。
其他構(gòu)造函數(shù)也類似,再看下析構(gòu)函數(shù):

template<typename T>
sp<T>::~sp() {
    if (m_ptr)
        m_ptr->decStrong(this);
}

析構(gòu)就是減少計(jì)數(shù),調(diào)用LightRefBase的decStrong,看下對(duì)應(yīng)的實(shí)現(xiàn):

   inline void decStrong(__attribute__((unused)) const void* id) const {
        if (mCount.fetch_sub(1, std::memory_order_release) == 1) {
            std::atomic_thread_fence(std::memory_order_acquire); // 利用屏障做線程同步
            delete static_cast<const T*>(this);
        }
    }

對(duì)計(jì)數(shù)減1,如果計(jì)數(shù)已經(jīng)是1了,難么減少后就是0,就需要調(diào)用下析構(gòu),把對(duì)象釋放掉。

強(qiáng)指針

強(qiáng)指針和弱指針對(duì)應(yīng)的結(jié)構(gòu)都是RefBase:

class RefBase
{
public:
            void            incStrong(const void* id) const;
            void            incStrongRequireStrong(const void* id) const;
            void            decStrong(const void* id) const;
    
            void            forceIncStrong(const void* id) const;

            //! DEBUGGING ONLY: Get current strong ref count.
            int32_t         getStrongCount() const;

    class weakref_type
    {
    public:
        RefBase*            refBase() const;

        void                incWeak(const void* id);
        void                incWeakRequireWeak(const void* id);
        void                decWeak(const void* id);

        // acquires a strong reference if there is already one.
        bool                attemptIncStrong(const void* id);

        // acquires a weak reference if there is already one.
        // This is not always safe. see ProcessState.cpp and BpBinder.cpp
        // for proper use.
        bool                attemptIncWeak(const void* id);

        //! DEBUGGING ONLY: Get current weak ref count.
        int32_t             getWeakCount() const;

        //! DEBUGGING ONLY: Print references held on object.
        void                printRefs() const;

        //! DEBUGGING ONLY: Enable tracking for this object.
        // enable -- enable/disable tracking
        // retain -- when tracking is enable, if true, then we save a stack trace
        //           for each reference and dereference; when retain == false, we
        //           match up references and dereferences and keep only the
        //           outstanding ones.

        void                trackMe(bool enable, bool retain);
    };

            weakref_type*   createWeak(const void* id) const;
            
            weakref_type*   getWeakRefs() const;

            //! DEBUGGING ONLY: Print references held on object.
    inline  void            printRefs() const { getWeakRefs()->printRefs(); }

            //! DEBUGGING ONLY: Enable tracking of object.
    inline  void            trackMe(bool enable, bool retain)
    { 
        getWeakRefs()->trackMe(enable, retain); 
    }

protected:
    // When constructing these objects, prefer using sp::make<>. Using a RefBase
    // object on the stack or with other refcount mechanisms (e.g.
    // std::shared_ptr) is inherently wrong. RefBase types have an implicit
    // ownership model and cannot be safely used with other ownership models.

                            RefBase();
    virtual                 ~RefBase();
    
    //! Flags for extendObjectLifetime()
    enum {
        OBJECT_LIFETIME_STRONG  = 0x0000,
        OBJECT_LIFETIME_WEAK    = 0x0001,
        OBJECT_LIFETIME_MASK    = 0x0001
    };
    
            void            extendObjectLifetime(int32_t mode);
            
    //! Flags for onIncStrongAttempted()
    enum {
        FIRST_INC_STRONG = 0x0001
    };
    
    // Invoked after creation of initial strong pointer/reference.
    virtual void            onFirstRef();
    // Invoked when either the last strong reference goes away, or we need to undo
    // the effect of an unnecessary onIncStrongAttempted.
    virtual void            onLastStrongRef(const void* id);
    // Only called in OBJECT_LIFETIME_WEAK case.  Returns true if OK to promote to
    // strong reference. May have side effects if it returns true.
    // The first flags argument is always FIRST_INC_STRONG.
    // TODO: Remove initial flag argument.
    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
    // Invoked in the OBJECT_LIFETIME_WEAK case when the last reference of either
    // kind goes away.  Unused.
    // TODO: Remove.
    virtual void            onLastWeakRef(const void* id);

private:
    friend class weakref_type;
    class weakref_impl;
    
                            RefBase(const RefBase& o);
            RefBase&        operator=(const RefBase& o);

private:
    friend class ReferenceMover;

    static void renameRefs(size_t n, const ReferenceRenamer& renamer);

    static void renameRefId(weakref_type* ref,
            const void* old_id, const void* new_id);

    static void renameRefId(RefBase* ref,
            const void* old_id, const void* new_id);

        weakref_impl* const mRefs;
};

可以看到對(duì)于強(qiáng)指針,并不是簡(jiǎn)單用一個(gè)原子變量來(lái)計(jì)數(shù)了,而是使用了weakref_impl,這是一個(gè)weakref_type類型,定義如下:

class RefBase::weakref_impl : public RefBase::weakref_type
{
public:
    std::atomic<int32_t>    mStrong;
    std::atomic<int32_t>    mWeak;
    RefBase* const          mBase;
    std::atomic<int32_t>    mFlags;

    explicit weakref_impl(RefBase* base)
        : mStrong(INITIAL_STRONG_VALUE)
        , mWeak(0)
        , mBase(base)
        , mFlags(0)
    {
    }
    void addStrongRef(const void* /*id*/) { }
    void removeStrongRef(const void* /*id*/) { }
    void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { }
    void addWeakRef(const void* /*id*/) { }
    void removeWeakRef(const void* /*id*/) { }
    void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { }
    void printRefs() const { }
    void trackMe(bool, bool) { }

可以看到RefBase提供了更多的能力,一個(gè)類繼承了RefBase就可以通過(guò)強(qiáng)指針和弱指針來(lái)使用了。強(qiáng)指針就是前面提到的sp,關(guān)鍵的還是incStrong和decStrong,現(xiàn)在再看下流程, 對(duì)于sp的incStorng,調(diào)用的是RefBase的incStrong

void RefBase::incStrong(const void* id) const
{
    weakref_impl* const refs = mRefs;
    refs->incWeak(id);
    
    refs->addStrongRef(id);
    const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed);
    ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
#if PRINT_REFS
    ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
    if (c != INITIAL_STRONG_VALUE)  {
        return;
    }

    int32_t old __unused = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE, std::memory_order_relaxed);
    // A decStrong() must still happen after us.
    ALOG_ASSERT(old > INITIAL_STRONG_VALUE, "0x%x too small", old);
    refs->mBase->onFirstRef();
}

可以看到先增加了弱引用,然后又添加了強(qiáng)引用,不過(guò)這兒并不是增加計(jì)數(shù),而是記錄引用指針,接下來(lái)才是增加計(jì)數(shù),如果不是首次增加就直接返回了,否則會(huì)調(diào)用onFirstRef。這樣如果有類想在第一次被引用的時(shí)候做些邏輯就可以使用這個(gè)機(jī)制了。
接下來(lái)看下incWeak和addStrongRef:

void RefBase::weakref_type::incWeak(const void* id)
{
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    impl->addWeakRef(id); // 添加弱引用
    const int32_t c __unused = impl->mWeak.fetch_add(1,
            std::memory_order_relaxed); // 增加計(jì)數(shù)
    ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
}

void addWeakRef(const void* id) {
    addRef(&mWeakRefs, id, mWeak.load(std::memory_order_relaxed));
}

void addStrongRef(const void* id) {
     //ALOGD_IF(mTrackEnabled,
     //        "addStrongRef: RefBase=%p, id=%p", mBase, id);
    addRef(&mStrongRefs, id, mStrong.load(std::memory_order_relaxed));
}

   // 記錄引用快照,這里面的引用計(jì)數(shù)是引用當(dāng)時(shí)的計(jì)數(shù),后續(xù)不會(huì)更新
    void addRef(ref_entry** refs, const void* id, int32_t mRef) 
    {
        if (mTrackEnabled) {
            AutoMutex _l(mMutex);

            ref_entry* ref = new ref_entry; 
            // Reference count at the time of the snapshot, but before the
            // update.  Positive value means we increment, negative--we
            // decrement the reference count.
            ref->ref = mRef;
            ref->id = id;
#if DEBUG_REFS_CALLSTACK_ENABLED
            ref->stack = CallStack::getCurrent(2);
#endif
            ref->next = *refs;
            *refs = ref;
        }
    }

看到這兒基本就把添加引用流程走完了,從這兒也可以看出來(lái)弱引用計(jì)數(shù)一定大于等于強(qiáng)引用計(jì)數(shù)。
再看下decStrong,調(diào)用的也是RefBase的decStrong

void RefBase::decStrong(const void* id) const
{
    weakref_impl* const refs = mRefs;
    refs->removeStrongRef(id); // 移除引用
    const int32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release); // 強(qiáng)引用計(jì)數(shù)減1
#if PRINT_REFS
    ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
    LOG_ALWAYS_FATAL_IF(BAD_STRONG(c), "decStrong() called on %p too many times",
            refs);
    if (c == 1) {
        std::atomic_thread_fence(std::memory_order_acquire);
        refs->mBase->onLastStrongRef(id); // 如果最后一個(gè)強(qiáng)引用,則調(diào)用下onLastStrongRef
        int32_t flags = refs->mFlags.load(std::memory_order_relaxed);
        if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
            delete this; // 如果是強(qiáng)引用關(guān)聯(lián)對(duì)象模式,則強(qiáng)引用為0時(shí)調(diào)用對(duì)象的析構(gòu)函數(shù) 
            // The destructor does not delete refs in this case.
        }
    }
    // Note that even with only strong reference operations, the thread
    // deallocating this may not be the same as the thread deallocating refs.
    // That's OK: all accesses to this happen before its deletion here,
    // and all accesses to refs happen before its deletion in the final decWeak.
    // The destructor can safely access mRefs because either it's deleting
    // mRefs itself, or it's running entirely before the final mWeak decrement.
    //
    // Since we're doing atomic loads of `flags`, the static analyzer assumes
    // they can change between `delete this;` and `refs->decWeak(id);`. This is
    // not the case. The analyzer may become more okay with this patten when
    // https://bugs.llvm.org/show_bug.cgi?id=34365 gets resolved. NOLINTNEXTLINE
    refs->decWeak(id);  // 減少弱引用
}

可以看到decStrong中的邏輯主要就是操作強(qiáng)引用計(jì)數(shù)和弱引用計(jì)數(shù)。再看下移除引用和減少弱引用的實(shí)現(xiàn):

    void removeStrongRef(const void* id) {
        //ALOGD_IF(mTrackEnabled,
        //        "removeStrongRef: RefBase=%p, id=%p", mBase, id);
        if (!mRetain) {
            removeRef(&mStrongRefs, id);
        } else {
            addRef(&mStrongRefs, id, -mStrong.load(std::memory_order_relaxed));
        }
    }

    void removeRef(ref_entry** refs, const void* id)  // 移除引用
    {
        if (mTrackEnabled) {
            AutoMutex _l(mMutex);
            
            ref_entry* const head = *refs;
            ref_entry* ref = head;
            while (ref != NULL) {
                if (ref->id == id) {
                    *refs = ref->next;
                    delete ref;
                    return;
                }
                refs = &ref->next;
                ref = *refs;
            }

            ALOGE("RefBase: removing id %p on RefBase %p"
                    "(weakref_type %p) that doesn't exist!",
                    id, mBase, this);

            ref = head;
            while (ref) {
                char inc = ref->ref >= 0 ? '+' : '-';
                ALOGD("\t%c ID %p (ref %d):", inc, ref->id, ref->ref);
                ref = ref->next;
            }

            CallStack::logStack(LOG_TAG);
        }
    }

再看下減少弱引用實(shí)現(xiàn):

void RefBase::weakref_type::decWeak(const void* id)
{
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    impl->removeWeakRef(id); // 移除弱引用指針
    const int32_t c = impl->mWeak.fetch_sub(1, std::memory_order_release); // 弱引用減1
    LOG_ALWAYS_FATAL_IF(BAD_WEAK(c), "decWeak called on %p too many times",
            this);
    if (c != 1) return;
    atomic_thread_fence(std::memory_order_acquire);

    int32_t flags = impl->mFlags.load(std::memory_order_relaxed);
    if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
        // This is the regular lifetime case. The object is destroyed
        // when the last strong reference goes away. Since weakref_impl
        // outlives the object, it is not destroyed in the dtor, and
        // we'll have to do it here.
        if (impl->mStrong.load(std::memory_order_relaxed)
                == INITIAL_STRONG_VALUE) {
            // Decrementing a weak count to zero when object never had a strong
            // reference.  We assume it acquired a weak reference early, e.g.
            // in the constructor, and will eventually be properly destroyed,
            // usually via incrementing and decrementing the strong count.
            // Thus we no longer do anything here.  We log this case, since it
            // seems to be extremely rare, and should not normally occur. We
            // used to deallocate mBase here, so this may now indicate a leak.
            ALOGW("RefBase: Object at %p lost last weak reference "
                    "before it had a strong reference", impl->mBase);
        } else {
            // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
            delete impl; // 弱應(yīng)用為0了,刪除析構(gòu)智能指針本身
        }
    } else {
        // This is the OBJECT_LIFETIME_WEAK case. The last weak-reference
        // is gone, we can destroy the object. // 如果是對(duì)象管理和弱引用關(guān)聯(lián),那么弱引用計(jì)數(shù)為0時(shí),需要析構(gòu)管理的對(duì)象。
        impl->mBase->onLastWeakRef(id);
        delete impl->mBase;
    }
}

到了這兒decStrong流程就結(jié)束了,主要就是減少?gòu)?qiáng)弱引用計(jì)數(shù)的值,并且在引用計(jì)數(shù)為0時(shí)按照對(duì)象管理策略進(jìn)行析構(gòu)對(duì)象。

弱指針

再看下弱指針的實(shí)現(xiàn),弱指針比較復(fù)雜一些:

template <typename T>
class wp
{
public:
    typedef typename RefBase::weakref_type weakref_type;

    inline wp() : m_ptr(nullptr), m_refs(nullptr) { }

    wp(T* other);  // NOLINT(implicit)
    wp(const wp<T>& other);
    explicit wp(const sp<T>& other);
    template<typename U> wp(U* other);  // NOLINT(implicit)
    template<typename U> wp(const sp<U>& other);  // NOLINT(implicit)
    template<typename U> wp(const wp<U>& other);  // NOLINT(implicit)

    ~wp();

    // Assignment

    wp& operator = (T* other);
    wp& operator = (const wp<T>& other);
    wp& operator = (const sp<T>& other);

    template<typename U> wp& operator = (U* other);
    template<typename U> wp& operator = (const wp<U>& other);
    template<typename U> wp& operator = (const sp<U>& other);

    void set_object_and_refs(T* other, weakref_type* refs);

    // promotion to sp

    sp<T> promote() const; // 由弱指針獲取一個(gè)強(qiáng)指針

    // Reset

    void clear();

    // Accessors

    inline  weakref_type* get_refs() const { return m_refs; }

    inline  T* unsafe_get() const { return m_ptr; }

    // Operators

    COMPARE_WEAK(==)
    COMPARE_WEAK(!=)
    COMPARE_WEAK_FUNCTIONAL(>, std::greater)
    COMPARE_WEAK_FUNCTIONAL(<, std::less)
    COMPARE_WEAK_FUNCTIONAL(<=, std::less_equal)
    COMPARE_WEAK_FUNCTIONAL(>=, std::greater_equal)

    template<typename U>
    inline bool operator == (const wp<U>& o) const {
        return m_refs == o.m_refs;  // Implies m_ptr == o.mptr; see invariants below.
    }

    template<typename U>
    inline bool operator == (const sp<U>& o) const {
        // Just comparing m_ptr fields is often dangerous, since wp<> may refer to an older
        // object at the same address.
        if (o == nullptr) {
          return m_ptr == nullptr;
        } else {
          return m_refs == o->getWeakRefs();  // Implies m_ptr == o.mptr.
        }
    }

    template<typename U>
    inline bool operator != (const sp<U>& o) const {
        return !(*this == o);
    }

    template<typename U>
    inline bool operator > (const wp<U>& o) const {
        if (m_ptr == o.m_ptr) {
            return _wp_compare_<std::greater>(m_refs, o.m_refs);
        } else {
            return _wp_compare_<std::greater>(m_ptr, o.m_ptr);
        }
    }

    template<typename U>
    inline bool operator < (const wp<U>& o) const {
        if (m_ptr == o.m_ptr) {
            return _wp_compare_<std::less>(m_refs, o.m_refs);
        } else {
            return _wp_compare_<std::less>(m_ptr, o.m_ptr);
        }
    }
    template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
    template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
    template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }

private:
    template<typename Y> friend class sp;
    template<typename Y> friend class wp;

    T*              m_ptr;
    weakref_type*   m_refs;
};

可以看到2點(diǎn):

  • 弱指針計(jì)數(shù)也是基于weakref_type,實(shí)際上就是weakref_impl,并不是自己維護(hù)一個(gè)計(jì)數(shù)
  • 弱指針沒(méi)有重載指針解引用等通過(guò)指針操作對(duì)象對(duì)象的運(yùn)算符,這樣通過(guò)弱引用就無(wú)法直接操作對(duì)象了。需要通過(guò)一個(gè)專門(mén)的函數(shù)promote獲取強(qiáng)指針才可以。
    接下來(lái)還是看三塊內(nèi)容,構(gòu)造,析構(gòu),promote。先看下構(gòu)造:
wp<T>::wp(T* other)
    : m_ptr(other)
{
    m_refs = other ? m_refs = other->createWeak(this) : nullptr;
}

m_ptr 保存對(duì)象指針,m_refs負(fù)責(zé)計(jì)數(shù),看下createWeak的實(shí)現(xiàn):

RefBase::weakref_type* RefBase::createWeak(const void* id) const
{
    mRefs->incWeak(id); // 添加引用,弱引用計(jì)數(shù)加1
    return mRefs;
}

void RefBase::weakref_type::incWeak(const void* id)
{
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    impl->addWeakRef(id);
    const int32_t c __unused = impl->mWeak.fetch_add(1,
            std::memory_order_relaxed);
    ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
}

再看下析構(gòu):

wp<T>::~wp()
{
    if (m_ptr) m_refs->decWeak(this); // 減少弱引用計(jì)數(shù)
}

再看下promote:

sp<T> wp<T>::promote() const
{
    sp<T> result;
    if (m_ptr && m_refs->attemptIncStrong(&result)) {
        result.set_pointer(m_ptr); // 因?yàn)閺?qiáng)引用計(jì)數(shù)已經(jīng)增加了,這兒只需要設(shè)置下對(duì)象指針
    }
    return result;
}

通過(guò)attemptIncStrong嘗試修改強(qiáng)引用計(jì)數(shù):

bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
    incWeak(id); // 弱引用計(jì)數(shù)加1
    
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    int32_t curCount = impl->mStrong.load(std::memory_order_relaxed);

    ALOG_ASSERT(curCount >= 0,
            "attemptIncStrong called on %p after underflow", this);

// 如果當(dāng)前強(qiáng)引用計(jì)數(shù)大于0,那么所管理的對(duì)象是有效的,那么更新強(qiáng)引用計(jì)數(shù)。
    while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
        // we're in the easy/common case of promoting a weak-reference
        // from an existing strong reference. 
        if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
                std::memory_order_relaxed)) {
            break;
        }
        // the strong count has changed on us, we need to re-assert our
        // situation. curCount was updated by compare_exchange_weak.
    }
    
    if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
        // we're now in the harder case of either:
        // - there never was a strong reference on us
        // - or, all strong references have been released
        int32_t flags = impl->mFlags.load(std::memory_order_relaxed);
        if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
            // this object has a "normal" life-time, i.e.: it gets destroyed
            // when the last strong reference goes away
            if (curCount <= 0) {
                // the last strong-reference got released, the object cannot
                // be revived.
                decWeak(id); // 如果強(qiáng)引用計(jì)數(shù)不大于0,而且是OBJECT_LIFETIME_STRONG,那么這時(shí)候?qū)ο笠呀?jīng)釋放了,獲取不到強(qiáng)指針了,把之前的弱引用加的計(jì)數(shù)減回去
                return false;
            }

            // here, curCount == INITIAL_STRONG_VALUE, which means
            // there never was a strong-reference, so we can try to
            // promote this object; we need to do that atomically.
            while (curCount > 0) { // 嘗試增加強(qiáng)引用計(jì)數(shù)
                if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
                        std::memory_order_relaxed)) {
                    break;
                }
                // the strong count has changed on us, we need to re-assert our
                // situation (e.g.: another thread has inc/decStrong'ed us)
                // curCount has been updated.
            }

            if (curCount <= 0) { // 增加強(qiáng)引用計(jì)數(shù)失敗了
                // promote() failed, some other thread destroyed us in the
                // meantime (i.e.: strong count reached zero).
                decWeak(id); 
                return false;
            }
        } else { // 這時(shí)候是由弱引用決定對(duì)象釋放時(shí)間點(diǎn),因此這時(shí)候?qū)ο罂赡軟](méi)有被釋放
            // this object has an "extended" life-time, i.e.: it can be
            // revived from a weak-reference only.
            // Ask the object's implementation if it agrees to be revived
            if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) { // 是否允許通過(guò)弱指針獲取強(qiáng)指針,目前的實(shí)現(xiàn)是一定會(huì)返回允許
                // it didn't so give-up.
                decWeak(id);
                return false;
            }
            // grab a strong-reference, which is always safe due to the
            // extended life-time.
            curCount = impl->mStrong.fetch_add(1, std::memory_order_relaxed); // 增加強(qiáng)引用計(jì)數(shù)
            // If the strong reference count has already been incremented by
            // someone else, the implementor of onIncStrongAttempted() is holding
            // an unneeded reference.  So call onLastStrongRef() here to remove it.
            // (No, this is not pretty.)  Note that we MUST NOT do this if we
            // are in fact acquiring the first reference.
            if (curCount != 0 && curCount != INITIAL_STRONG_VALUE) {
                impl->mBase->onLastStrongRef(id);
            }
        }
    }
    
    impl->addStrongRef(id); // 記錄強(qiáng)引用

#if PRINT_REFS
    ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
#endif

    // curCount is the value of mStrong before we incremented it.
    // Now we need to fix-up the count if it was INITIAL_STRONG_VALUE.
    // This must be done safely, i.e.: handle the case where several threads
    // were here in attemptIncStrong().
    // curCount > INITIAL_STRONG_VALUE is OK, and can happen if we're doing
    // this in the middle of another incStrong.  The subtraction is handled
    // by the thread that started with INITIAL_STRONG_VALUE.
    if (curCount == INITIAL_STRONG_VALUE) { // 如果是首次增加,那么需要調(diào)整計(jì)數(shù),因?yàn)殚_(kāi)始默認(rèn)值是INITIAL_STRONG_VALUE, 需要把這個(gè)數(shù)減掉才是正確的計(jì)數(shù)值
        impl->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
                std::memory_order_relaxed);
    }

    return true;
}

到了這兒關(guān)于弱指針的內(nèi)容也介紹完了。
最后畫(huà)一個(gè)圖總結(jié)下輕量級(jí)指針,強(qiáng)指針,弱指針的關(guān)系:


類關(guān)系圖
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容