<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                我們首先分析RefBase類的實現原理,它的定義如下所示。 **frameworks/base/include/utils/RefBase.h** ~~~ class RefBase { public: void incStrong(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 decWeak(const void* id); bool attemptIncStrong(const void* id); //! This is only safe if you have set OBJECT_LIFETIME_FOREVER. 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: RefBase(); virtual ~RefBase(); //! Flags for extendObjectLifetime() enum { OBJECT_LIFETIME_WEAK = 0x0001, OBJECT_LIFETIME_FOREVER = 0x0003 }; void extendObjectLifetime(int32_t mode); //! Flags for onIncStrongAttempted() enum { FIRST_INC_STRONG = 0x0001 }; virtual void onFirstRef(); virtual void onLastStrongRef(const void* id); virtual bool onIncStrongAttempted(uint32_t flags, const void* id); virtual void onLastWeakRef(const void* id); private: friend class weakref_type; class weakref_impl; RefBase(const RefBase& o); RefBase& operator=(const RefBase& o); weakref_impl* const mRefs; }; ~~~ 與LightRefBase類一樣,RefBase類也提供了成員函數incStrong和decStrong來維護它所引用的對象的引用計數。不過,RefBase類與LightRefBase類不一樣,它不是直接使用一個整數來維護對象的引用計數的,而是使用一個weakref_impl對象,即成員變量mRefs來描述對象的引用計數。 weakref_impl類同時為對象提供了強引用計數和弱引用計數,它的實現如下所示。 **frameworks/base/libs/utils/RefBase.cpp** ~~~ class RefBase::weakref_impl : public RefBase::weakref_type { public: volatile int32_t mStrong; volatile int32_t mWeak; RefBase* const mBase; volatile int32_t mFlags; #if !DEBUG_REFS 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 addWeakRef(const void* /*id*/) { } void removeWeakRef(const void* /*id*/) { } void printRefs() const { } void trackMe(bool, bool) { } #else ...... #endif }; ~~~ weakref_impl類繼承了weakref_type類。weakref_type類定義在RefBase類的內部,它提供了成員函數incWeak、decWeak、attemptIncStrong和attemptIncWeak來維護對象的強引用計數和弱引用計數。weakref_type類只定義了引用計數維護接口,具體的實現是由weakref_impl類提供的。 weakref_impl類有兩個成員變量mStrong和mWeak,分別用來描述對象的強引用計數和弱引用計數。同時,weakref_impl類的成員變量mBase指向了它所引用的對象的地址,而成員變量mFlags是一個標志值,用來描述對象的生命周期控制方式。weakref_impl類的成員變量mFlags的取值范圍為0、OBJECT_LIFETIME_WEAK或者OBJECT_LIFETIME_FOREVER,其中,0表示對象的生命周期只受強引用計數影響;OBJECT_LIFETIME_WEAK表示對象的生命周期同時受強引用計數和弱引用計數影響;OBJECT_LIFETIME_FOREVER表示對象的生命周期完全不受強引用計數或者弱引用計數影響。 weakref_impl類的實現有調試和非調試兩個版本,它們是通過宏DEBUG_REFS來區別的。如果定義了宏DEBUG_REFS,則weakref_impl類被編譯成調試版本;否則被編譯成非調試版本。weakref_impl類的調試版本只是用于調試它本身的實現,我們不關心,因此省略了這些代碼。 下面我們就通過一個類圖來總結RefBase、weakref_type和weakref_impl三個類的關系,如圖3-1所示。 ![ RefBase、weakref_type和weakref_impl類的關系](https://box.kancloud.cn/4829f723f5b3f26efd053f5d9b0e5463_631x316.jpg =631x316) 從這個類圖就可以看出,每一個RefBase對象都包含了一個weakref_impl對象,而后者繼承了weakref_type類。在接下來的內容中,我們會進一步介紹這三個類的作用及其關系。 強指針的實現類為sp,在前面的3.1.1小節中,我們只分析了它的輕量級指針實現。在本節中,我們將分析sp類的強指針實現,主要是分析它的構造函數和析構函數的實現。 sp類的構造函數的實現如下所示。 **frameworks/base/include/utils/RefBase.h** ~~~ template<typename T> sp<T>::sp(T* other) : m_ptr(other) { if (other) other->incStrong(this); } ~~~ > 注意:模塊參數T是一個繼承了RefBase類的子類,因此,第5行實際上是調用了RefBase類的成員函數incStrong來增加對象的強引用計數,如下所示。 **frameworks/base/libs/utils/RefBase.cpp** ~~~ void RefBase::incStrong(const void* id) const { weakref_impl* const refs = mRefs; refs->addWeakRef(id); refs->incWeak(id); refs->addStrongRef(id); const int32_t c = android_atomic_inc(&refs->mStrong); LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs); #if PRINT_REFS LOGD("incStrong of %p from %p: cnt=%d\n", this, id, c); #endif if (c != INITIAL_STRONG_VALUE) { return; } android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); const_cast<RefBase*>(this)->onFirstRef(); } ~~~ RefBase類的成員變量mRefs是在構造函數中初始化的,如下所示。 **frameworks/base/libs/utils/RefBase.cpp** ~~~ RefBase::RefBase() : mRefs(new weakref_impl(this)) { // LOGV("Creating refs %p with RefBase %p\n", mRefs, this); } ~~~ 回到RefBase類的成員函數incStrong中,它主要做了三件事情:第一件事情是調用第5行代碼來增加對象的弱引用計數;第二件事情是調用第8行代碼來增加對象的強引用計數;第三件事情是如果發現對象是第一次被強指針引用,則第20行調用對象的成員函數onFirstRef來通知對象,它被強指針引用了,以便它可以執行一些業務相關邏輯。RefBase類的成員函數onFirstRef是一個空實現,如果子類想要處理這個事件,那么就必須要重寫成員函數onFirstRef。 增加對象的弱引用計數是通過調用RefBase類的成員變量mRefs的成員函數incWeak來實現的。RefBase類的成員變量mRefs的類型為weakref_impl,它的成員函數incWeak是從父類weakref_type繼承下來的,因此,它實際上是通過調用weakref_type類的成員函數incWeak來增加對象的弱引用計數的,如下所示。 **frameworks/base/libs/utils/RefBase.cpp** ~~~ void RefBase::weakref_type::incWeak(const void* id) { weakref_impl* const impl = static_cast<weakref_impl*>(this); impl->addWeakRef(id); const int32_t c = android_atomic_inc(&impl->mWeak); LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this); } ~~~ this指針指向的實際上是一個weakref_impl對象,因此,第3行將它轉換為一個weakref_impl指針impl。有了這個impl指針之后,我們就可以訪問它的成員變量mWeak了。第5行調用函數android_atomic_inc來增加它的成員變量mWeak的值,即增加對象的弱引用計數。第4行的函數調用是與調試相關的,我們忽略它的實現。 回到RefBase類的成員函數incStrong中,增加了對象的弱引用計數之后,接下來就調用函數android_atomic_inc來增加對象的強引用計數了,即增加RefBase類的引用計數對象mRefs的成員變量mStrong的值。函數android_atomic_inc的返回值是對象原來的強引用計數值,即加1前的值。在weakref_impl類的構造函數中,成員變量mStrong的值被初始化為INITIAL_STRONG_VALUE。INITIAL_STRONG_VALUE是一個宏,它的定義如下所示。 **frameworks/base/libs/utils/RefBase.cpp** ~~~ #define INITIAL_STRONG_VALUE (1<<28) ~~~ 從理論上說,當對象第一次被強指針引用時,它的強引用計數值應該等于1,但是我們看到,對象的強引用計數的初始值為INITIAL_STRONG_VALUE,它加1之后并不等于1,因此,RefBase類的成員函數incStrong需要將它調整為1,如第19行代碼所示。 至此,強指針類sp的構造函數的實現就分析完了,它主要做的事情就是增加對象的強引用計數和弱引用計數。從這里就可以看出,雖然我們的目的是增加對象的強引用計數,但是同時也會增加對象的弱引用計數,即一個對象的弱引用計數一定是大于或者等于它的強引用計數的。 下面我們再來分析sp類的析構函數的實現,如下所示。 **frameworks/base/include/utils/RefBase.h** ~~~ template<typename T> sp<T>::~sp() { if (m_ptr) m_ptr->decStrong(this); } ~~~ 前面提到,sp類的成員變量m_ptr所指向的對象是繼承了RefBase類的,因此,第4行實際上是調用了RefBase類的成員函數decStrong來減少對象的強引用計數,它的實現如下所示。 **frameworks/base/libs/utils/RefBase.cpp** ~~~ void RefBase::decStrong(const void* id) const { weakref_impl* const refs = mRefs; refs->removeStrongRef(id); const int32_t c = android_atomic_dec(&refs->mStrong); #if PRINT_REFS LOGD("decStrong of %p from %p: cnt=%d\n", this, id, c); #endif LOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs); if (c == 1) { const_cast<RefBase*>(this)->onLastStrongRef(id); if ((refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) { delete this; } } refs->removeWeakRef(id); refs->decWeak(id); } ~~~ 我們忽略第4行和第16行代碼,因為它們在非調試版本中是空函數調用。sp類的析構函數執行的操作剛好與構造函數相反,它主要是減少對象的強引用計數和弱引用計數。 第5行代碼通過調用函數android_atomic_dec來減少對象的強引用計數。與函數android_atomic_inc類似,函數android_atomic_dec的返回值是對象原來的強引用計數值,即減1前的值,保存在變量c中。如果變量c的值等于1,就說明此時再也沒有強指針引用這個對象了,因此,第11行就調用該對象的成員函數onLastStrongRef來使得它可以執行一些業務相關的邏輯,同時也要考慮是否需要釋放該對象。第12行檢查對象的生命周期是否受弱引用計數控制,即RefBase類的成員變量mRefs的標志值mFlags的OBJECT_LIFETIME_WEAK位是否等于1。如果不等于1,就說明對象的生命周期不受弱引用計數影響,因此,第13行就會釋放對象所占用的內存,這同時會導致RefBase類的析構函數被調用。 **frameworks/base/libs/utils/RefBase.cpp** ~~~ RefBase::~RefBase() { // LOGV("Destroying RefBase %p (refs %p)\n", this, mRefs); if (mRefs->mWeak == 0) { // LOGV("Freeing refs %p of old RefBase %p\n", mRefs, this); delete mRefs; } } ~~~ 在RefBase類的析構函數中,如果發現對象的弱引用計數值為0,那么就會把引用計數對象mRefs也一起釋放。RefBase類的成員變量mRefs指向的是一個weakref_impl對象,它是在RefBase類的構造函數中創建的。現在既然它所屬的RefBase對象已經不存在了,并且它所引用的對象的弱引用計數值也等于0,它也就不需要存在了。前面提到,一個對象的弱引用計數一定是大于等于它的強引用計數的,因此,當一個對象的強引用計數值為0時,它的弱引用計數值可能大于0。在對象的弱引用計數值大于0的情況下,我們只能將對應的RefBase對象釋放掉,而不能將該RefBase對象內部的weakref_impl對象也釋放掉,因為還有其他的弱指針通過該weakref_impl對象來引用實際的對象。只有當對象的弱引用計數值也為0 時,才可以將該weakref_impl對象也一起釋放掉。 回到RefBase類的成員函數decStrong中,第17行代碼執行減少對象的弱引用計數的操作。變量refs指向的是RefBase類內部的weakref_impl對象mRefs。weakref_impl類的成員函數decWeak是從父類weakref_type繼承下來的,因此,接下來實際執行的是weakref_type類的成員函數decWeak,它的實現如下所示。 **frameworks/base/libs/utils/RefBase.cpp** ~~~ void RefBase::weakref_type::decWeak(const void* id) { weakref_impl* const impl = static_cast<weakref_impl*>(this); impl->removeWeakRef(id); const int32_t c = android_atomic_dec(&impl->mWeak); LOG_ASSERT(c >= 1, "decWeak called on %p too many times", this); if (c != 1) return; if ((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) { if (impl->mStrong == INITIAL_STRONG_VALUE) delete impl->mBase; else { // LOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase); delete impl; } } else { impl->mBase->onLastWeakRef(id); if ((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) { delete impl->mBase; } } } ~~~ 第4行的函數調用在非調試版本中是空函數調用,我們將它忽略。第5行調用android_atomic_dec函數來減少對象的弱引用計數,并且返回減少之前的值,保存在變量c中。如果c的值不等于1,那么就說明還有其他的弱指針在引用這個對象,因此,就不用進一步處理了;如果c的值等于1,那么就說明再也沒有弱指針引用這個對象了,同時也說明沒有強指針引用這個對象了,因為當對象的弱引用計數值等于0時,它的強引用計數值也一定等于0。在對象的弱引用計數值等于0時,我們就要考慮是否需要將該對象釋放掉。這取決于對象的生命周期控制方式,以及該對象是否被強指針引用過。下面我們分為兩種情況來考慮。 第一種情況是對象的生命周期只受強引用計數控制,即第9行的if語句為true。此時如果第10行的if語句也為true,即對象從來沒有被強指針引用過,那么在該對象的弱引用計數值等于0時,第11行就需要將該對象釋放掉;否則,這個對象以后就會得不到釋放。當一個只受強引用計數控制的對象只被弱指針引用時,就會出現這種情況。如果對象的生命周期只受強引用計數控制,并且它也被強指針引用過,那么在該對象的弱引用計數值變為0時,該對象就已經在RefBase類的成員函數decStrong中被釋放,因此,第14行只負責釋放其內部的引用計數器對象weakref_impl。 第二種情況是對象的生命周期受弱引用計數控制,即第9行的if語句為false。第17行首先調用對象的成員函數onLastWeakRef來使得它可以執行一些業務相關的邏輯,同時也要考慮是否需要將該對象釋放掉。第18行檢查對象的生命周期是否完全不受強引用計數和弱引用計數控制,即RefBase類的成員變量mRefs的標志值mFlags的OBJECT_LIFETIME_FOREVER位是否等于1。如果不等于1,那么第19行就會釋放對象所占用的內存。 從第二種情況就可以看出,當對象的生命周期控制標志值設置為OBJECT_LIFETIME_FOREVER時,即對象的生命周期完全不受強引用計數和弱引用計數控制時,Android系統所提供的智能指針就退化成一個普通的C++指針了,這時候開發人員就需要手動地釋放那些不再使用了的對象所占用的內存。 至此,強指針的實現原理就分析完了。為了加深對它的理解,我們對對象的生命周期控制方式作一個小結。 (1)如果一個對象的生命周期控制標志值被設置為0,那么只要它的強引用計數值為0,系統就會自動釋放這個對象。 (2)如果一個對象的生命周期控制標志值被設置為OBJECT_LIFETIME_WEAK,那么只有當它的強引用計數值和弱引用計數值都為0時,系統才會自動釋放這個對象。 (3)如果一個對象的生命周期控制標志值被設置為OBJECT_LIFETIME_FOREVER,那么系統就 永遠不會自動釋放這個對象,它需要由開發人員來手動地釋放。 接下來,我們繼續分析弱指針的實現原理。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看