日本好好热aⅴ|国产99视频精品免费观看|日本成人aV在线|久热香蕉国产在线

  • <cite id="ikgdy"><table id="ikgdy"></table></cite>
    1. 西西軟件下載最安全的下載網(wǎng)站、值得信賴的軟件下載站!

      首頁(yè)編程開(kāi)發(fā)Android → Android指針管理:RefBase,SP,WP、通過(guò)引用計(jì)數(shù)來(lái)實(shí)現(xiàn)智能指針

      Android指針管理:RefBase,SP,WP、通過(guò)引用計(jì)數(shù)來(lái)實(shí)現(xiàn)智能指針

      相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來(lái)源:AngelDevil時(shí)間:2013/3/10 12:54:05字體大。A-A+

      作者:AngelDevil點(diǎn)擊:0次評(píng)論:0次標(biāo)簽: 指針

      • 類(lèi)型:系統(tǒng)優(yōu)化大。76M語(yǔ)言:中文 評(píng)分:6.0
      • 標(biāo)簽:
      立即下載

      Android中通過(guò)引用計(jì)數(shù)來(lái)實(shí)現(xiàn)智能指針,并且實(shí)現(xiàn)有強(qiáng)指針與弱指針。由對(duì)象本身來(lái)提供引用計(jì)數(shù)器,但是對(duì)象不會(huì)去維護(hù)引用計(jì)數(shù)器的值,而是由智能指針來(lái)管理。

      要達(dá)到所有對(duì)象都可用引用計(jì)數(shù)器實(shí)現(xiàn)智能指針管理的目標(biāo),可以定義一個(gè)公共類(lèi),提供引用計(jì)數(shù)的方法,所有對(duì)象都去繼承這個(gè)公共類(lèi),這樣就可以實(shí)現(xiàn)所有對(duì)象都可以用引用計(jì)數(shù)來(lái)管理的目標(biāo),在Android中,這個(gè)公共類(lèi)就是RefBase,同時(shí)還有一個(gè)簡(jiǎn)單版本LightRefBase。

      RefBase作為公共基類(lèi)提供了引用計(jì)數(shù)的方法,但是并不去維護(hù)引用計(jì)數(shù)的值,而是由兩個(gè)智能指針來(lái)進(jìn)行管理:sp(Strong Pointer)和wp(Weak Pointer),代表強(qiáng)引用計(jì)數(shù)和弱引用計(jì)數(shù)。

      一、輕量級(jí)引用計(jì)數(shù)的實(shí)現(xiàn):LightRefBase

      template <class T>
      class LightRefBase
      {
      public:
      inline LightRefBase() : mCount(0) { }
      inline void incStrong(const void* id) const {
      android_atomic_inc(&mCount);
      }
      inline void decStrong(const void* id) const {
      if (android_atomic_dec(&mCount) == 1) {
      delete static_cast<const T*>(this);
      }
      }
      //! DEBUGGING ONLY: Get current strong ref count.
      inline int32_t getStrongCount() const {
      return mCount;
      }
      typedef LightRefBase<T> basetype;
      protected:
      inline ~LightRefBase() { }
      private:
      mutable volatile int32_t mCount;
      };
      LightRefBase的實(shí)現(xiàn)很簡(jiǎn)單,只是內(nèi)部保存了一個(gè)變量用于保存對(duì)象被引用的次數(shù),并提供了兩個(gè)函數(shù)用于增加或減少引用計(jì)數(shù)。

      二、sp(Strong Pointer)

      LightRefBase僅僅提供了引用計(jì)數(shù)的方法,具體引用數(shù)應(yīng)該怎么管理,就要通過(guò)智能指針類(lèi)來(lái)管理了,每當(dāng)有一個(gè)智能指針指向?qū)ο髸r(shí),對(duì)象的引用計(jì)數(shù)要加1,當(dāng)一個(gè)智能指針取消指向?qū)ο髸r(shí),對(duì)象的引用計(jì)數(shù)要減1,在C++中,當(dāng)一個(gè)對(duì)象生成和銷(xiāo)毀時(shí)會(huì)自動(dòng)調(diào)用(拷貝)構(gòu)造函數(shù)和析構(gòu)函數(shù),所以,對(duì)對(duì)象引用數(shù)的管理就可以放到智能指針的(拷貝)構(gòu)造函數(shù)和析構(gòu)函數(shù)中。Android提供了一個(gè)智能指針可以配合LightRefBase使用:sp,sp的定義如下:

      template <typename T>
      class sp
      {
      public:
      inline sp() : m_ptr(0) { }
      sp(T* other);
      sp(const sp<T>& other);

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

      ~sp();

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

      template<typename U> sp& operator = (const 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; }

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

      代碼比較多,其中Accessors部分代碼重載了*、->操作符使我們使用sp的時(shí)候就像使用真實(shí)的對(duì)象指針一樣,可以直接操作對(duì)象的屬性或方法,COMPARE是宏定義,用于重載關(guān)系操作符,由于對(duì)引用計(jì)數(shù)的控制主要是由(拷貝)構(gòu)造函數(shù)和析構(gòu)函數(shù)控制,所以忽略其他相關(guān)代碼后,sp可以精簡(jiǎn)為如下形式(賦值操作符也省略掉了,構(gòu)造函數(shù)省略相似的兩個(gè)):

      template <typename T>
      class sp
      {
      public:
      inline sp() : m_ptr(0) { }
      sp(T* other);
      sp(const sp<T>& other);

      ~sp();

      private:
      template<typename Y> friend class sp;
      template<typename Y> friend class wp;
      void set_pointer(T* ptr);
      T* m_ptr;
      };
      默認(rèn)構(gòu)造函數(shù)使智能指針不指向任何對(duì)象,sp(T* other)與sp(const sp<T>& other)的實(shí)現(xiàn)如下:

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

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

      內(nèi)部變量m_ptr指向?qū)嶋H對(duì)象,并調(diào)用實(shí)際對(duì)象的incStrong函數(shù),T繼承自LightRefBase,所以此處調(diào)用的是LightRefBase的incStrong函數(shù),之后實(shí)際對(duì)象的引用計(jì)數(shù)加1。

      當(dāng)智能指針?shù)N毀的時(shí)候調(diào)用智能指針的析構(gòu)函數(shù):

      template<typename T>
      sp<T>::~sp()
      {
      if (m_ptr) m_ptr->decStrong(this);
      }
      調(diào)用實(shí)際對(duì)象即LightRefBase的decStrong函數(shù),其實(shí)現(xiàn)如下:

      inline void decStrong(const void* id) const {
      if (android_atomic_dec(&mCount) == 1) {
      delete static_cast<const T*>(this);
      }
      }
      android_atomic_dec返回mCount減1之前的值,如果返回1表示這次減過(guò)之后引用計(jì)數(shù)就是0了,就把對(duì)象delete掉。

      三、RefBase

      RefBase提供了更強(qiáng)大的引用計(jì)數(shù)的管理。

      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);
      // 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);
      }
      typedef RefBase basetype;

      protected:
      RefBase();
      virtual ~RefBase();

      //! Flags for extendObjectLifetime()
      enum {
      OBJECT_LIFETIME_STRONG = 0x0000,
      OBJECT_LIFETIME_WEAK = 0x0001,
      OBJECT_LIFETIME_MASK = 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內(nèi)部并沒(méi)有使用一個(gè)變量來(lái)維護(hù)引用計(jì)數(shù),而是通過(guò)一個(gè)weakref_impl *類(lèi)型的成員來(lái)維護(hù)引用計(jì)數(shù),并且同時(shí)提供了強(qiáng)引用計(jì)數(shù)和弱引用計(jì)數(shù)。weakreef_impl繼承于RefBase::weakref_type,代碼比較多,不過(guò)大都是調(diào)試代碼,由宏定義分開(kāi),Release是不包含高度代碼的,去除這些代碼后其定義為:

      #define INITIAL_STRONG_VALUE (1<<28)

      class RefBase::weakref_impl : public RefBase::weakref_type
      {
      public:
      volatile int32_t mStrong;
      volatile int32_t mWeak;
      RefBase* const mBase;
      volatile int32_t mFlags;

      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) { }
      };
      weakref_impl中的函數(shù)都是作為調(diào)試用,Release版的實(shí)現(xiàn)都是空的,成員變量分別表示強(qiáng)引用數(shù)、弱引用數(shù)、指向?qū)嶋H對(duì)象的指針與flag,flag可控制實(shí)際對(duì)象的生命周期,取值為0或RefBase中定義的枚舉值。

      RefBase提供了incStrong與decStrong函數(shù)用于控制強(qiáng)引用計(jì)數(shù)值,其弱引用計(jì)數(shù)值是由weakref_impl控制,強(qiáng)引用計(jì)數(shù)與弱引用數(shù)都保存在weakref_impl *類(lèi)型的成員變量mRefs中。

      RefBase同LightRefBase一樣為對(duì)象提供了引用計(jì)數(shù)的方法,對(duì)引用計(jì)數(shù)的管理同樣要由智能指針控制,由于RefBase同時(shí)實(shí)現(xiàn)了強(qiáng)引用計(jì)數(shù)與弱引用計(jì)數(shù),所以就有兩種類(lèi)型的智能指針,sp(Strong Pointer)與wp(Weak Pointer)。

      sp前面已經(jīng)說(shuō)過(guò),其(拷貝)構(gòu)造函數(shù)調(diào)用對(duì)象即RefBase的incStrong函數(shù)。

      void RefBase::incStrong(const void* id) const
      {
      weakref_impl* const refs = mRefs;
      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 (c != INITIAL_STRONG_VALUE) {
      return;
      }
      android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
      refs->mBase->onFirstRef();
      }
      addStrong的函數(shù)體為空,incStrong函數(shù)內(nèi)部首先調(diào)用成員變量mRefs的incWeak函數(shù)將弱引用數(shù)加1,然后再將強(qiáng)引用數(shù)加1,由于android_atomic_inc返回變量的舊值,所以如果其不等于INITIAL_STRONG_VALUE就直接返回,則則是第一次由強(qiáng)智能指針(sp)引用,將其減去INITIAL_STRONG_VALUE后變成1,然后調(diào)用對(duì)象的onFirstRef。

      成員變量mRefs是在對(duì)象的構(gòu)造函數(shù)中初始化的:

      RefBase::RefBase()
      : mRefs(new weakref_impl(this))
      {
      }
      weakrel_impl的incWeak繼承自父類(lèi)weakrel_type的incWeak:

      void RefBase::weakref_type::incWeak(const void* id)
      {
      weakref_impl* const impl = static_cast<weakref_impl*>
      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);
      }
      addWeakRef實(shí)現(xiàn)同樣為空,所以只是將弱引用計(jì)數(shù)加1。所以當(dāng)對(duì)象被sp引用后,強(qiáng)引用計(jì)數(shù)與弱引用計(jì)數(shù)會(huì)同時(shí)加1。

      當(dāng)sp銷(xiāo)毀時(shí)其析構(gòu)函數(shù)調(diào)用對(duì)象即RefBase的decStrong函數(shù):

      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 (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);
      }
      decStrong中將強(qiáng)引用數(shù)與弱引用數(shù)同時(shí)減1,如果這是最后一個(gè)強(qiáng)引用的話,會(huì)調(diào)用對(duì)象的onLastStrongRef,并且判斷成員變量mRefs的成員變量mFlags來(lái)決定是否在對(duì)象的強(qiáng)引用數(shù)為0時(shí)釋放對(duì)象。

      mFlags可以為0或以下兩個(gè)枚舉值:

      enum {
      OBJECT_LIFETIME_WEAK = 0x0001,
      OBJECT_LIFETIME_FOREVER = 0x0003
      };
      mFlags的值可以通過(guò)extendObjectLifetime函數(shù)改變:

      1
      2
      3
      4
      void RefBase::extendObjectLifetime(int32_t mode)
      {
      android_atomic_or(mode, &mRefs->mFlags);
      }
      OBJECT_LIFETIME_FOREVER包含OBJECT_LIFETIME_WEAK(位運(yùn)算中其二進(jìn)制11包含01),所以當(dāng)

      refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
      為true時(shí)表示mFlags為0,實(shí)際對(duì)象的生命周期受強(qiáng)引用數(shù)控制,所以在強(qiáng)引用數(shù)為0時(shí)delete this,否則實(shí)際對(duì)象的生命周期就由弱引用數(shù)控制。

      再來(lái)看decWeak:

      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);
      if (c != 1) return;

      if ((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
      if (impl->mStrong == INITIAL_STRONG_VALUE)
      delete impl->mBase;
      else {
      delete impl;
      }
      } else {
      impl->mBase->onLastWeakRef(id);
      if ((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) {
      delete impl->mBase;
      }
      }
      }
      將弱引用數(shù)減1,若減1后不為0直接返回,否則判斷

      (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
      判斷結(jié)果為true:

      實(shí)際對(duì)象生命周期被強(qiáng)引用數(shù)控制,接下來(lái)判斷:

      mpl->mStrong == INITIAL_STRONG_VALUE
      如果判斷為true表示對(duì)象只被弱引用引用過(guò),現(xiàn)在弱引用數(shù)為0,直接刪除實(shí)際對(duì)象。

      如果判斷為false,表示對(duì)象曾經(jīng)被強(qiáng)引用引用過(guò),但現(xiàn)在強(qiáng)引用為變?yōu)?了(因?yàn)樵黾踊驕p小強(qiáng)引用數(shù)時(shí)一定同時(shí)增加或減小弱引用數(shù),所以弱引用數(shù)為0時(shí),強(qiáng)引用數(shù)一定為0),弱引用數(shù)為0了,直接釋放mRefs,而實(shí)際對(duì)象由于受強(qiáng)引用數(shù)控制,已經(jīng)在RefBase::decStrong中被delete了。

      判斷結(jié)果為false:

      判斷mFlgs是否是OBJECT_LIFETIME_FOREVER,如果是,什么都不作由用戶自己控制對(duì)象的生命周期,否則,實(shí)際對(duì)象的生命周期受弱引用數(shù)控制,現(xiàn)在弱引用數(shù)為0,delete實(shí)際對(duì)象。

      四、wp(Weak Pointer)

      定義如下:

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

      inline wp() : m_ptr(0) { }

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

      ~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;

      // Reset

      void clear();

      // Accessors

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

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

      // Operators

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

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

      T* m_ptr;
      weakref_type* m_refs;
      };
      同sp一樣,m_ptr指向?qū)嶋H對(duì)象,但wp還有一個(gè)成員變量m_refs。

      template<typename T>
      wp<T>::wp(T* other)
      : m_ptr(other)
      {
      if (other) m_refs = other->createWeak(this);
      }

      template<typename T>
      wp<T>::wp(const wp<T>& other)
      : m_ptr(other.m_ptr), m_refs(other.m_refs)
      {
      if (m_ptr) m_refs->incWeak(this);
      }

      RefBase::weakref_type* RefBase::createWeak(const void* id) const
      {
      mRefs->incWeak(id);
      return mRefs;
      }
      可以看到,wp的m_refs就是RefBase即實(shí)際對(duì)象的mRefs。

      wp析構(gòu)的時(shí)候減少弱引用計(jì)數(shù):

      template<typename T>
      wp<T>::~wp()
      {
      if (m_ptr) m_refs->decWeak(this);
      }
      由于弱指針沒(méi)有重載*與->操作符,所以不能直接操作指向的對(duì)象,雖然有unsafe_get函數(shù),但像名字所示的,不建議使用,直接使用實(shí)際對(duì)象指針的話就沒(méi)必要用智能指針了。

      因?yàn)槿踔羔槻荒苤苯硬僮鲗?duì)象,所以要想操作對(duì)象的話就要將其轉(zhuǎn)換為強(qiáng)指針,即wp::promote方法:

      template<typename T>
      sp<T> wp<T>::promote() const
      {
      return sp<T>(m_ptr, m_refs);
      }

      template<typename T>
      sp<T>::sp(T* p, weakref_type* refs)
      : m_ptr((p && refs->attemptIncStrong(this)) ? p : 0)
      {
      }
      是否能從弱指針生成一個(gè)強(qiáng)指針關(guān)鍵是看refs->attemptIncStrong,看其定義:

      bool RefBase::weakref_type::attemptIncStrong(const void* id)
      {
      incWeak(id);

      weakref_impl* const impl = static_cast<weakref_impl*>(this);

      int32_t curCount = impl->mStrong;
      LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",
      this);
      while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
      if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
      break;
      }
      curCount = impl->mStrong;
      }

      if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
      bool allow;
      if (curCount == INITIAL_STRONG_VALUE) {
      // Attempting to acquire first strong reference... this is allowed
      // if the object does NOT have a longer lifetime (meaning the
      // implementation doesn't need to see this), or if the implementation
      // allows it to happen.
      allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
      || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
      } else {
      // Attempting to revive the object... this is allowed
      // if the object DOES have a longer lifetime (so we can safely
      // call the object with only a weak ref) and the implementation
      // allows it to happen.
      allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK
      && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
      }
      if (!allow) {
      decWeak(id);
      return false;
      }
      curCount = android_atomic_inc(&impl->mStrong);

      // 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->addWeakRef(id);
      impl->addStrongRef(id);

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

      if (curCount == INITIAL_STRONG_VALUE) {
      android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);
      impl->mBase->onFirstRef();
      }

      return true;
      }
      首先通過(guò)incWeak將弱引用數(shù)加1(被強(qiáng)指針sp引用會(huì)導(dǎo)致強(qiáng)引用數(shù)和弱引用數(shù)同時(shí)加1),然后:

      int32_t curCount = impl->mStrong;
      while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
      if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
      break;
      }
      curCount = impl->mStrong;
      }
      如果之前已經(jīng)有強(qiáng)引用,直接將強(qiáng)引用數(shù)加1,android_atomic_cmpxchg表示如果impl->mStrong的值為curCount,則把impl->mString的值改為curCount+1,此處用while循環(huán)是防止其他線程已經(jīng)增加了強(qiáng)引用數(shù)。

      接下來(lái):

      if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE)
      表示對(duì)象目前沒(méi)有強(qiáng)引用,這就要判斷對(duì)象是否存在了。

      如果curCount == INITIAL_STRONG_VALUE,表示對(duì)象沒(méi)有被sp引用過(guò)。接下來(lái)判斷:

      allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
      || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
      表示:如果對(duì)象的生命周期只受強(qiáng)引用控制,對(duì)象一定存在,要有強(qiáng)引用才可以管理對(duì)象的釋放,所以一定會(huì)允許生成強(qiáng)引用;如果對(duì)象的生命周期受弱引用控制,調(diào)用對(duì)象的onIncStrongAttempted試圖增加強(qiáng)引用,由于此時(shí)在弱引用中,弱引用一定不為0,對(duì)象也一定存在,調(diào)用onIncStrongAttempted的意圖是因?yàn)轭?lèi)的實(shí)現(xiàn)者可能不希望用強(qiáng)引用引用對(duì)象。在RefBase中onIncStrongAttempted默認(rèn)返回true:

      bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id)
      {
      return (flags&FIRST_INC_STRONG) ? true : false;
      }
      如果curCount <= 0(只會(huì)等于0),表示對(duì)象強(qiáng)引用數(shù)經(jīng)歷了INITIAL_STRONG_VALUE -->大于0 --> 0,接下來(lái)就要判斷:

      allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK
      && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
      如果對(duì)象的生命周期受強(qiáng)引用數(shù)控制,那么由于曾被sp引用過(guò),現(xiàn)在強(qiáng)引用數(shù)又為0,對(duì)象就已經(jīng)被delete了,所以就不能生成強(qiáng)引用,否則如果對(duì)象的生命周期受弱引用數(shù)控制,就通過(guò)onIncStrongAttempted看類(lèi)的實(shí)現(xiàn)者是否希望當(dāng)對(duì)象的強(qiáng)引用數(shù)變?yōu)?時(shí)可以再次被強(qiáng)引用引用。

      if (!allow) {
      decWeak(id);
      return false;
      }
      如果allow為false表示不能從弱引用生成強(qiáng)引用,就要調(diào)用decWeak將弱引用減1(因?yàn)樵趐romote入口先將弱引用加了1),然后返回false表示生成強(qiáng)引用失敗。

      if (curCount == INITIAL_STRONG_VALUE) {
      android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);
      impl->mBase->onFirstRef();
      }
      最后,如果curCount == INITIAL_STRONG_VALUE表示第一次被sp引用,調(diào)用對(duì)象的onFirstRef函數(shù)。

      五、總結(jié)

      RefBase內(nèi)部有一個(gè)指針指向?qū)嶋H對(duì)象,有一個(gè)weakref_impl類(lèi)型的指針保存對(duì)象的強(qiáng)/弱引用計(jì)數(shù)、對(duì)象生命周期控制。sp只有一個(gè)成員變量,用來(lái)保存實(shí)際對(duì)象,但這個(gè)實(shí)際對(duì)象內(nèi)部已包含了weakref_impl *對(duì)象用于保存實(shí)際對(duì)象的引用計(jì)數(shù)。sp 管理一個(gè)對(duì)象指針時(shí),對(duì)象的強(qiáng)、弱引用數(shù)同時(shí)加1,sp銷(xiāo)毀時(shí),對(duì)象的強(qiáng)、弱引用數(shù)同時(shí)減1。

      wp中有兩個(gè)成員變量,一個(gè)保存實(shí)際對(duì)象,另一個(gè)是weakref_impl *對(duì)象。wp管理一個(gè)對(duì)象指針時(shí),對(duì)象的弱引用計(jì)數(shù)加1,wp銷(xiāo)毀時(shí),對(duì)象的弱引用計(jì)數(shù)減1。

      weakref_impl中包含一個(gè)flag用于決定對(duì)象的生命周期是由強(qiáng)引用數(shù)控制還是由弱引用數(shù)控制:

      當(dāng)flag為0時(shí),實(shí)際對(duì)象的生命周期由強(qiáng)引用數(shù)控制,weakref_impl *對(duì)象由弱引用數(shù)控制。

      當(dāng)flag為OBJECT_LIFETIME_WEAK時(shí),實(shí)際對(duì)象的生命周期受弱引用數(shù)控制。

      當(dāng)flag為OBJECT_LIFETIME_FOREVER時(shí),實(shí)際對(duì)象的生命周期由用戶控制。

      可以用extendObjectLifetime改變flag的值。

        相關(guān)評(píng)論

        閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

        • 8 喜歡喜歡
        • 3 頂
        • 1 難過(guò)難過(guò)
        • 5 囧
        • 3 圍觀圍觀
        • 2 無(wú)聊無(wú)聊

        熱門(mén)評(píng)論

        最新評(píng)論

        發(fā)表評(píng)論 查看所有評(píng)論(0)

        昵稱:
        表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
        字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過(guò)審核才能顯示)