<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Android指針管理:RefBase,SP,WP

      Android中通過引用計數來實現智能指針,并且實現有強指針與弱指針。由對象本身來提供引用計數器,但是對象不會去維護引用計數器的值,而是由智能指針來管理。

      要達到所有對象都可用引用計數器實現智能指針管理的目標,可以定義一個公共類,提供引用計數的方法,所有對象都去繼承這個公共類,這樣就可以實現所有對象都可以用引用計數來管理的目標,在Android中,這個公共類就是RefBase,同時還有一個簡單版本LightRefBase。

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

      一、輕量級引用計數的實現:LightRefBase

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

      二、sp(Strong Pointer)

      LightRefBase僅僅提供了引用計數的方法,具體引用數應該怎么管理,就要通過智能指針類來管理了,每當有一個智能指針指向對象時,對象的引用計數要加1,當一個智能指針取消指向對象時,對象的引用計數要減1,在C++中,當一個對象生成和銷毀時會自動調用(拷貝)構造函數和析構函數,所以,對對象引用數的管理就可以放到智能指針的(拷貝)構造函數和析構函數中。Android提供了一個智能指針可以配合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的時候就像使用真實的對象指針一樣,可以直接操作對象的屬性或方法,COMPARE是宏定義,用于重載關系操作符,由于對引用計數的控制主要是由(拷貝)構造函數和析構函數控制,所以忽略其他相關代碼后,sp可以精簡為如下形式(賦值操作符也省略掉了,構造函數省略相似的兩個):

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

      默認構造函數使智能指針不指向任何對象,sp(T* other)與sp(const sp<T>& other)的實現如下:

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

      內部變量m_ptr指向實際對象,并調用實際對象的incStrong函數,T繼承自LightRefBase,所以此處調用的是LightRefBase的incStrong函數,之后實際對象的引用計數加1。

      當智能指針銷毀的時候調用智能指針的析構函數:

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

      調用實際對象即LightRefBase的decStrong函數,其實現如下:

      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表示這次減過之后引用計數就是0了,就把對象delete掉。

      三、RefBase

      RefBase提供了更強大的引用計數的管理。

      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內部并沒有使用一個變量來維護引用計數,而是通過一個weakref_impl *類型的成員來維護引用計數,并且同時提供了強引用計數和弱引用計數。weakref_impl繼承于RefBase::weakref_type,代碼比較多,不過大都是調試代碼,由宏定義分開,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中的函數都是作為調試用,Release版的實現都是空的,成員變量分別表示強引用數、弱引用數、指向實際對象的指針與flag,flag可控制實際對象的生命周期,取值為0或RefBase中定義的枚舉值。

      RefBase提供了incStrong與decStrong函數用于控制強引用計數值,其弱引用計數值是由weakref_impl控制,強引用計數與弱引用數都保存在weakref_impl *類型的成員變量mRefs中。

      RefBase同LightRefBase一樣為對象提供了引用計數的方法,對引用計數的管理同樣要由智能指針控制,由于RefBase同時實現了強引用計數與弱引用計數,所以就有兩種類型的智能指針,sp(Strong Pointer)與wp(Weak Pointer)。

      sp前面已經說過,其(拷貝)構造函數調用對象即RefBase的incStrong函數。

      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的函數體為空,incStrong函數內部首先調用成員變量mRefs的incWeak函數將弱引用數加1,然后再將強引用數加1,由于android_atomic_inc返回變量的舊值,所以如果其不等于INITIAL_STRONG_VALUE就直接返回,則則是第一次由強智能指針(sp)引用,將其減去INITIAL_STRONG_VALUE后變成1,然后調用對象的onFirstRef。

      成員變量mRefs是在對象的構造函數中初始化的:

      RefBase::RefBase()
          : mRefs(new weakref_impl(this))
      {
      }

      weakrel_impl的incWeak繼承自父類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實現同樣為空,所以只是將弱引用計數加1。所以當對象被sp引用后,強引用計數與弱引用計數會同時加1。

      當sp銷毀時其析構函數調用對象即RefBase的decStrong函數:

      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中將強引用數與弱引用數同時減1,如果這是最后一個強引用的話,會調用對象的onLastStrongRef,并且判斷成員變量mRefs的成員變量mFlags來決定是否在對象的強引用數為0時釋放對象。

      mFlags可以為0或以下兩個枚舉值:

      enum {
          OBJECT_LIFETIME_WEAK    = 0x0001,
          OBJECT_LIFETIME_FOREVER    = 0x0003
      };

      mFlags的值可以通過extendObjectLifetime函數改變:

      void RefBase::extendObjectLifetime(int32_t mode)
      {
          android_atomic_or(mode, &mRefs->mFlags);
      }

      OBJECT_LIFETIME_FOREVER包含OBJECT_LIFETIME_WEAK(位運算中其二進制11包含01),所以當

      refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK

      為true時表示mFlags為0,實際對象的生命周期受強引用數控制,所以在強引用數為0時delete this,否則實際對象的生命周期就由弱引用數控制。

      再來看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; 
              } 
          } 
      }

      將弱引用數減1,若減1后不為0直接返回,否則判斷

      (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK

      若判斷結果為true:

          實際對象生命周期被強引用數控制,接下來判斷:

      mpl->mStrong == INITIAL_STRONG_VALUE
      1. 如果判斷為true表示對象只被弱引用引用過,現在弱引用數為0,直接刪除實際對象。

      2. 如果判斷為false,表示對象曾經被強引用引用過,但現在強引用為變為0了(因為增加或減小強引用數時一定同時增加或減小弱引用數,所以弱引用數為0時,強引用數一定為0),弱引用數為0了,直接釋放mRefs,而實際對象由于受強引用數控制,已經在RefBase::decStrong中被delete了。

      若判斷結果為false:

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

      四、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指向實際對象,但wp還有一個成員變量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即實際對象的mRefs。

      wp析構的時候減少弱引用計數:

      template<typename T>
      wp<T>::~wp()
      {
          if (m_ptr) m_refs->decWeak(this);
      }

      由于弱指針沒有重載*與->操作符,所以不能直接操作指向的對象,雖然有unsafe_get函數,但像名字所示的,不建議使用,直接使用實際對象指針的話就沒必要用智能指針了。

      因為弱指針不能直接操作對象,所以要想操作對象的話就要將其轉換為強指針,即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)
      {
      }

      是否能從弱指針生成一個強指針關鍵是看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;
      }

      首先通過incWeak將弱引用數加1(被強指針sp引用會導致強引用數和弱引用數同時加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;
      }

      如果之前已經有強引用,直接將強引用數加1,android_atomic_cmpxchg表示如果impl->mStrong的值為curCount,則把impl->mString的值改為curCount+1,此處用while循環是防止其他線程已經增加了強引用數。

      接下來:

      if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE)

      表示對象目前沒有強引用,這就要判斷對象是否存在了。

      如果curCount == INITIAL_STRONG_VALUE,表示對象沒有被sp引用過。接下來判斷:

      allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
          || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
       

      表示:如果對象的生命周期只受強引用控制,對象一定存在,要有強引用才可以管理對象的釋放,所以一定會允許生成強引用;如果對象的生命周期受弱引用控制,調用對象的onIncStrongAttempted試圖增加強引用,由于此時在弱引用中,弱引用一定不為0,對象也一定存在,調用onIncStrongAttempted的意圖是因為類的實現者可能不希望用強引用引用對象。在RefBase中onIncStrongAttempted默認返回true:

      bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id)
      {
          return (flags&FIRST_INC_STRONG) ? true : false;
      }

      如果curCount <= 0(只會等于0),表示對象強引用數經歷了INITIAL_STRONG_VALUE -->大于0 --> 0,接下來就要判斷:

      allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK
          && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);

      如果對象的生命周期受強引用數控制,那么由于曾被sp引用過,現在強引用數又為0,對象就已經被delete了,所以就不能生成強引用,否則如果對象的生命周期受弱引用數控制,就通過onIncStrongAttempted看類的實現者是否希望當對象的強引用數變為0時可以再次被強引用引用。

       
      if (!allow) {
          decWeak(id);
          return false;
      }

      如果allow為false表示不能從弱引用生成強引用,就要調用decWeak將弱引用減1(因為在promote入口先將弱引用加了1),然后返回false表示生成強引用失敗。

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

      最后,如果curCount == INITIAL_STRONG_VALUE表示第一次被sp引用,調用對象的onFirstRef函數。

      五、總結

      RefBase內部有一個指針指向實際對象,有一個weakref_impl類型的指針保存對象的強/弱引用計數、對象生命周期控制。

      sp只有一個成員變量,用來保存實際對象,但這個實際對象內部已包含了weakref_impl *對象用于保存實際對象的引用計數。sp 管理一個對象指針時,對象的強、弱引用數同時加1,sp銷毀時,對象的強、弱引用數同時減1。

      wp中有兩個成員變量,一個保存實際對象,另一個是weakref_impl *對象。wp管理一個對象指針時,對象的弱引用計數加1,wp銷毀時,對象的弱引用計數減1。

      weakref_impl中包含一個flag用于決定對象的生命周期是由強引用數控制還是由弱引用數控制:

      • 當flag為0時,實際對象的生命周期由強引用數控制,weakref_impl *對象由弱引用數控制。

      • 當flag為OBJECT_LIFETIME_WEAK時,實際對象的生命周期受弱引用數控制。

      • 當flag為OBJECT_LIFETIME_FOREVER時,實際對象的生命周期由用戶控制。

              可以用extendObjectLifetime改變flag的值。

      posted @ 2013-03-10 12:48  AngelDevil  閱讀(19531)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 综合色一色综合久久网| 亚洲人成网网址在线看| 亚洲另类无码一区二区三区| 麻豆精品一区二区综合av| 国产亚洲精品黑人粗大精选| 久久天天躁狠狠躁夜夜婷| 国产成人无码aa片免费看| 一区二区三区四区激情视频| 玩弄放荡人妻少妇系列| 欧美猛少妇色xxxxx| 国产区一区二区现看视频| 中文字幕人妻无码一夲道| 奇米四色7777中文字幕| 亚洲av成人久久18禁| 国产精品免费AⅤ片在线观看| 欧洲亚洲精品免费二区| 国产午夜精品福利免费不| 日韩精品 在线 国产 丝袜| 亚洲午夜久久久久久噜噜噜| 麻豆国产成人AV在线播放| 又粗又硬又黄a级毛片| 国产农村老熟女国产老熟女| 人体内射精一区二区三区| 丝袜美腿亚洲综合在线观看视频 | 亚洲一区久久蜜臀av| 麻豆国产va免费精品高清在线| 日韩有码中文字幕第一页| 伊人大杳焦在线| 国产亚洲另类无码专区| 午夜精品久久久久久99热| 99久久精品久久久久久婷婷| 日本熟妇色xxxxx日本免费看| 国产区精品福利在线熟女| 狠狠色噜噜狠狠亚洲AV| 国产95在线 | 欧美| 中文字幕日韩精品有码| 日韩精品中文字幕有码| 欧美牲交a欧美牲交aⅴ图片| 久久午夜无码鲁丝片直播午夜精品| 国产偷国产偷亚洲高清午夜| 亚洲2022国产成人精品无码区|