Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1495698
  • 博文数量: 267
  • 博客积分: 3010
  • 博客等级: 少校
  • 技术积分: 3089
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-05 17:09
个人简介

尊天命,尽人事

文章分类

全部博文(267)

文章存档

2017年(6)

2015年(4)

2014年(27)

2013年(52)

2012年(59)

2011年(120)

分类: Android平台

2013-05-02 19:10:22

原文地址:http://www.cnblogs.com/angeldevil/archive/2013/03/10/2952586.html
       
       Android中通过引用计数来实现智能指针,并且实现有强指针与弱指针。由对象本身来提供引用计数器,但是对象不会去维护引用计数器的值,而是由智能指针来管理。

        要达到所有对象都可用引用计数器实现智能指针管理的目标,可以定义一个公共类,提供引用计数的方法,所有对象都去继承这个公共类, 这样就可以实现所有对象都可以用引用计数来管理的目标,在Android中,这个公共类就是RefBase,同时还有一个简单版本 LightRefBase。

        RefBase作为公共基类提供了引用计数的方法,但是并不去维护引用计数的值,而是由两个智能指针来进行管理:sp(Strong Pointer)和wp(Weak Pointer),代表强引用计数和弱引用计数。
一、轻量级引用计数的实现:LightRefBase

  1. template <class T>
  2. class LightRefBase
  3. {
  4. public:
  5.     inline LightRefBase() : mCount(0) { }
  6.     inline void incStrong(const void* id) const {
  7.         android_atomic_inc(&mCount);
  8.     }
  9.     inline void decStrong(const void* id) const {
  10.         if (android_atomic_dec(&mCount) == 1) {
  11.             delete static_cast<const T*>(this);
  12.         }
  13.     }
  14.     //! DEBUGGING ONLY: Get current strong ref count.
  15.     inline int32_t getStrongCount() const {
  16.         return mCount;
  17.     }
  18.     typedef LightRefBase<T> basetype;
  19. protected:
  20.     inline ~LightRefBase() { }
  21. private:
  22.     mutable volatile int32_t mCount;
  23. };
        LightRefBase的实现很简单,只是内部保存了一个变量用于保存对象被引用的次数,并提供了两个函数用于增加或减少引用计数。

二、sp(Strong Pointer)

        LightRefBase仅仅提供了引用计数的方法,具体引用数应该怎么管理,就要通过智能指针类来管理了,每当有一个智能指针指 向对象时,对象的引用计数要加1,当一个智能指针取消指向对象时,对象的引用计数要减1,在C++中,当一个对象生成和销毁时会自动调用(拷贝)构造函数 和析构函数,所以,对对象引用数的管理就可以放到智能指针的(拷贝)构造函数和析构函数中。Android提供了一个智能指针可以配合 LightRefBase使用:sp,sp的定义如下:


  1. template <typename T>
  2. class sp
  3. {
  4. public:
  5.     inline sp() : m_ptr(0) { }
  6.     sp(T* other);
  7.     sp(const sp<T>& other);
  8.                                           
  9.     template<typename U> sp(U* other);
  10.     template<typename U> sp(const sp<U>& other);
  11.                                         
  12.     ~sp();
  13.                                           
  14.     // Assignment
  15.     sp& operator = (T* other);
  16.     sp& operator = (const sp<T>& other);
  17.                                           
  18.     template<typename U> sp& operator = (const sp<U>& other);
  19.     template<typename U> sp& operator = (U* other);
  20.                                           
  21.     //! Special optimization for use by ProcessState (and nobody else).
  22.     void force_set(T* other);
  23.                                           
  24.     // Reset
  25.     void clear();
  26.                                           
  27.     // Accessors
  28.     inline T& operator* () const { return *m_ptr; }
  29.     inline T* operator-> () const { return m_ptr; }
  30.     inline T* get() const { return m_ptr; }
  31.                                           
  32.     // Operators
  33.     COMPARE(==)
  34.     COMPARE(!=)
  35.     COMPARE(>)
  36.     COMPARE(<)
  37.     COMPARE(<=)
  38.     COMPARE(>=)
  39. private:
  40.     template<typename Y> friend class sp;
  41.     template<typename Y> friend class wp;
  42.     void set_pointer(T* ptr);
  43.     T* m_ptr;
  44. }
        代码比较多,其中Accessors部分代码重载了*、->操作符使我们使用sp的时候就像使用真实的对象指针一样,可以直接操作 对象的属性或方法,COMPARE是宏定义,用于重载关系操作符,由于对引用计数的控制主要是由(拷贝)构造函数和析构函数控制,所以忽略其他相关代码 后,sp可以精简为如下形式(赋值操作符也省略掉了,构造函数省略相似的两个):

  1. template <typename T>
  2. class sp
  3. {
  4. public:
  5.     inline sp() : m_ptr(0) { }
  6.     sp(T* other);
  7.     sp(const sp<T>& other);
  8.                                         
  9.     ~sp();
  10.                                         
  11. private:
  12.     template<typename Y> friend class sp;
  13.     template<typename Y> friend class wp;
  14.     void set_pointer(T* ptr);
  15.     T* m_ptr;
  16. }
        默认构造函数使智能指针不指向任何对象,sp(T* other)与sp(const sp& other)的实现如下:

  1. template<typename T>
  2. sp<T>::sp(T* other)
  3. : m_ptr(other)
  4. {
  5.     if (other) other->incStrong(this);
  6. }
  7.                                        
  8. template<typename T>
  9. sp<T>::sp(const sp<T>& other)
  10. : m_ptr(other.m_ptr)
  11. {
  12.     if (m_ptr) m_ptr->incStrong(this);
  13. }

        内部变量m_ptr指向实际对象,并调用实际对象的incStrong函数,T继承自LightRefBase,所以此处调用的是LightRefBase的incStrong函数,之后实际对象的引用计数加1。

        当智能指针销毁的时候调用智能指针的析构函数:


  1. template<typename T>
  2. sp<T>::~sp()
  3. {
  4.     if (m_ptr) m_ptr->decStrong(this);
  5. }
       调用实际对象即LightRefBase的decStrong函数,其实现如下:

  1. inline void decStrong(const void* id) const {
  2.     if (android_atomic_dec(&mCount) == 1) {
  3.         delete static_cast<const T*>(this);
  4.     }
  5. }
android_atomic_dec返回mCount减1之前的值,如果返回1表示这次减过之后引用计数就是0了,就把对象delete掉。

三、RefBase

        RefBase提供了更强大的引用计数的管理。

 

  1. class RefBase
  2. {
  3. public:
  4.     void incStrong(const void* id) const;
  5.     void decStrong(const void* id) const;
  6.     void forceIncStrong(const void* id) const;
  7.     //! DEBUGGING ONLY: Get current strong ref count.
  8.     int32_t getStrongCount() const;
  9.                                  
  10.     class weakref_type
  11.     {
  12.     public:
  13.         RefBase refBase() const;
  14.         void incWeak(const void* id);
  15.         void decWeak(const void* id);
  16.         // acquires a strong reference if there is already one.
  17.         bool attemptIncStrong(const void* id);
  18.         // acquires a weak reference if there is already one.
  19.         // This is not always safe. see ProcessState.cpp and BpBinder.cpp
  20.         // for proper use.
  21.         bool attemptIncWeak(const void* id);
  22.         //! DEBUGGING ONLY: Get current weak ref count.
  23.         int32_t getWeakCount() const;
  24.         //! DEBUGGING ONLY: Print references held on object.
  25.         void printRefs() const;
  26.         //! DEBUGGING ONLY: Enable tracking for this object.
  27.         // enable -- enable/disable tracking
  28.         // retain -- when tracking is enable, if true, then we save a stack trace
  29.         // for each reference and dereference; when retain == false, we
  30.         // match up references and dereferences and keep only the
  31.         // outstanding ones.
  32.         void trackMe(bool enable, bool retain);
  33.     };
  34.     weakref_type* createWeak(const void* id) const;
  35.     weakref_type* getWeakRefs() const;
  36.     // DEBUGGING ONLY: Print references held on object.
  37.     inline void printRefs() const { getWeakRefs()->printRefs(); }
  38.     // DEBUGGING ONLY: Enable tracking of object.
  39.     inline void trackMe(bool enable, bool retain)
  40.     {
  41.         getWeakRefs()->trackMe(enable, retain);
  42.     }
  43.     typedef RefBase basetype;
  44.                                      
  45. protected:
  46.     RefBase();
  47.     virtual ~RefBase();
  48.                                      
  49.     //! Flags for extendObjectLifetime()
  50.     enum {
  51.         OBJECT_LIFETIME_STRONG = 0x0000,
  52.         OBJECT_LIFETIME_WEAK = 0x0001,
  53.         OBJECT_LIFETIME_MASK = 0x0003
  54.     };
  55.                                      
  56.     void extendObjectLifetime(int32_t mode);
  57.     //! Flags for onIncStrongAttempted()
  58.     enum {
  59.         FIRST_INC_STRONG = 0x0001
  60.     };
  61.                                      
  62.     virtual void onFirstRef();
  63.     virtual void onLastStrongRef(const void* id);
  64.     virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
  65.     virtual void onLastWeakRef(const void* id);
  66.                                      
  67. private:
  68.     friend class weakref_type;
  69.     class weakref_impl;
  70.                                      
  71.     RefBase(const RefBase& o);
  72.     RefBase& operator=(const RefBase& o);
  73.     weakref_impl* const mRefs;
  74. }


        不同于LightRefBase的是,RefBase内部并没有使用一个变量来维护引用计数,而是通过一个 weakref_impl *类型的成员来维护引用计数,并且同时提供了强引用计数和弱引用计数。weakreef_impl继承于 RefBase::weakref_type,代码比较多,不过大都是调试代码,由宏定义分开,Release是不包含高度代码的,去除这些代码后其定义 为:

点击(此处)折叠或打开

  1. #define INITIAL_STRONG_VALUE (1<<28)
  2.                                 
  3. class RefBase::weakref_impl : public RefBase::weakref_type
  4. {
  5. public:
  6.     volatile int32_t mStrong;
  7.     volatile int32_t mWeak;
  8.     RefBase* const mBase;
  9.     volatile int32_t mFlags;
  10.                                    
  11.     weakref_impl(RefBase* base)
  12.         : mStrong(INITIAL_STRONG_VALUE)
  13.         , mWeak(0)
  14.         , mBase(base)
  15.         , mFlags(0)
  16.     {
  17.     }
  18.                                    
  19.     void addStrongRef(const void* /*id*/) { }
  20.     void removeStrongRef(const void* /*id*/) { }
  21.     void addWeakRef(const void* /*id*/) { }
  22.     void removeWeakRef(const void* /*id*/) { }
  23.     void printRefs() const { }
  24.     void trackMe(bool, bool) { }
  25. }

         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函数。

  1. void RefBase::incStrong(const void* id) const
  2. {
  3.     weakref_impl* const refs = mRefs;
  4.     refs->incWeak(id);
  5.     refs->addStrongRef(id);
  6.     const int32_t c = android_atomic_inc(&refs->mStrong);
  7.     LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
  8.     if (c != INITIAL_STRONG_VALUE) {
  9.         return;
  10.     }
  11.     android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
  12.     refs->mBase->onFirstRef();
  13. }
        addStrong的函数体为空,incStrong函数内部首先调用成员变量mRefs的incWeak函数将弱引用数加1,然后再将 强引用数加1,由于android_atomic_inc返回变量的旧值,所以如果其不等于INITIAL_STRONG_VALUE就直接返回,则则是 第一次由强智能指针(sp)引用,将其减去INITIAL_STRONG_VALUE后变成1,然后调用对象的onFirstRef。


        成员变量mRefs是在对象的构造函数中初始化的:

点击(此处)折叠或打开

  1. RefBase::RefBase()
  2.     : mRefs(new weakref_impl(this))
  3. {
  4. }
        weakrel_impl的incWeak继承自父类weakrel_type的incWeak:
  1. void RefBase::weakref_type::incWeak(const void* id)
  2. {
  3.     weakref_impl* const impl = static_cast<weakref_impl*>
  4.     impl->addWeakRef(id);
  5.     const int32_t c = android_atomic_inc(&impl->mWeak);
  6.     LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
  7. }

        addWeakRef实现同样为空,所以只是将弱引用计数加1。所以当对象被sp引用后,强引用计数与弱引用计数会同时加1。

        当sp销毁时其析构函数调用对象即RefBase的decStrong函数:


  1. void RefBase::decStrong(const void* id) const
  2. {
  3.     weakref_impl* const refs = mRefs;
  4.     refs->removeStrongRef(id);
  5.     const int32_t c = android_atomic_dec(&refs->mStrong);
  6.     if (c == 1) {
  7.         const_cast<RefBase*>(this)->onLastStrongRef(id);
  8.         if ((refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
  9.             delete this;
  10.         }
  11.     }
  12.     refs->removeWeakRef(id);
  13.     refs->decWeak(id);
  14. }

        decStrong中将强引用数与弱引用数同时减1,如果这是最后一个强引用的话,会调用对象的onLastStrongRef,并且判断成员变量mRefs的成员变量mFlags来决定是否在对象的强引用数为0时释放对象。

        mFlags可以为0或以下两个枚举值:


点击(此处)折叠或打开

  1. enum {
  2.     OBJECT_LIFETIME_WEAK = 0x0001,
  3.     OBJECT_LIFETIME_FOREVER = 0x0003
  4. }
        mFlags的值可以通过extendObjectLifetime函数改变:

  1. void RefBase::extendObjectLifetime(int32_t mode)
  2. {
  3.     android_atomic_or(mode, &mRefs->mFlags);
  4. }
       OBJECT_LIFETIME_FOREVER包含OBJECT_LIFETIME_WEAK(位运算中其二进制11包含01),所以当

  1. refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK

        为true时表示mFlags为0,实际对象的生命周期受强引用数控制,所以在强引用数为0时delete this,否则实际对象的生命周期就由弱引用数控制。

        再来看decWeak:


  1. void RefBase::weakref_type::decWeak(const void* id)
  2. {
  3.     weakref_impl* const impl = static_cast<weakref_impl*>(this);
  4.     impl->removeWeakRef(id);
  5.     const int32_t c = android_atomic_dec(&impl->mWeak);
  6.     if (c != 1) return;
  7.                           
  8.     if ((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
  9.         if (impl->mStrong == INITIAL_STRONG_VALUE)
  10.             delete impl->mBase;
  11.         else {
  12.             delete impl;
  13.         }
  14.     } else {
  15.         impl->mBase->onLastWeakRef(id);
  16.         if ((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) {
  17.             delete impl->mBase;
  18.         }
  19.     }
  20. }
       将弱引用数减1,若减1后不为0直接返回,否则判断

  1. (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
    1. 判断结果为true:

实际对象生命周期被强引用数控制,接下来判断:

mpl->mStrong == INITIAL_STRONG_VALUE
  1. 如果判断为true表示对象只被弱引用引用过,现在弱引用数为0,直接删除实际对象。

  2. 如果判断为false,表示对象曾经被强引用引用过,但现在强引用为变为0了(因为增加或减小强引用数时一定同时增加或减小弱引用数,所以弱引用数 为0时,强引用数一定为0),弱引用数为0了,直接释放mRefs,而实际对象由于受强引用数控制,已经在RefBase::decStrong中被 delete了。

  1. 判断结果为false:

    判断mFlgs是否是OBJECT_LIFETIME_FOREVER,如果是,什么都不作由用户自己控制对象的生命周期,否则,实际对象的生命周期受弱引用数控制,现在弱引用数为0,delete实际对象。

四、wp(Weak Pointer)

        定义如下:


  1. template <typename T>
  2. class wp
  3. {
  4. public:
  5.     typedef typename RefBase::weakref_type weakref_type;
  6.                      
  7.     inline wp() : m_ptr(0) { }
  8.                  
  9.     wp(T* other);
  10.     wp(const wp<T>& other);
  11.     wp(const sp<T>& other);
  12.     template<typename U> wp(U* other);
  13.     template<typename U> wp(const sp<U>& other);
  14.     template<typename U> wp(const wp<U>& other);
  15.                  
  16.     ~wp();
  17.                      
  18.     // Assignment
  19.                  
  20.     wp& operator = (T* other);
  21.     wp& operator = (const wp<T>& other);
  22.     wp& operator = (const sp<T>& other);
  23.                      
  24.     template<typename U> wp& operator = (U* other);
  25.     template<typename U> wp& operator = (const wp<U>& other);
  26.     template<typename U> wp& operator = (const sp<U>& other);
  27.                      
  28.     void set_object_and_refs(T* other, weakref_type* refs);
  29.                  
  30.     // promotion to sp
  31.                      
  32.     sp<T> promote() const;
  33.                  
  34.     // Reset
  35.                      
  36.     void clear();
  37.                  
  38.     // Accessors
  39.                      
  40.     inline weakref_type* get_refs() const { return m_refs; }
  41.                      
  42.     inline T* unsafe_get() const { return m_ptr; }
  43.                  
  44.     // Operators
  45.                          
  46.     COMPARE(==)
  47.     COMPARE(!=)
  48.     COMPARE(>)
  49.     COMPARE(<)
  50.     COMPARE(<=)
  51.     COMPARE(>=)
  52.                  
  53. private:
  54.     template<typename Y> friend class sp;
  55.     template<typename Y> friend class wp;
  56.                  
  57.     T* m_ptr;
  58.     weakref_type* m_refs;
  59. }
同sp一样,m_ptr指向实际对象,但wp还有一个成员变量m_refs。


  1. template<typename T>
  2. wp<T>::wp(T* other)
  3.     : m_ptr(other)
  4. {
  5.     if (other) m_refs = other->createWeak(this);
  6. }
  7.                   
  8. template<typename T>
  9. wp<T>::wp(const wp<T>& other)
  10.     : m_ptr(other.m_ptr), m_refs(other.m_refs)
  11. {
  12.     if (m_ptr) m_refs->incWeak(this);
  13. }
  14.                  
  15. RefBase::weakref_type* RefBase::createWeak(const void* id) const
  16. {
  17.     mRefs->incWeak(id);
  18.     return mRefs;
  19. }

        可以看到,wp的m_refs就是RefBase即实际对象的mRefs。

        wp析构的时候减少弱引用计数:


  1. template<typename T>
  2. wp<T>::~wp()
  3. {
  4.     if (m_ptr) m_refs->decWeak(this);
  5. }

        由于弱指针没有重载*与->操作符,所以不能直接操作指向的对象,虽然有unsafe_get函数,但像名字所示的,不建议使用,直接使用实际对象指针的话就没必要用智能指针了。

        因为弱指针不能直接操作对象,所以要想操作对象的话就要将其转换为强指针,即wp::promote方法:


  1. template<typename T>
  2. sp<T> wp<T>::promote() const
  3. {
  4.     return sp<T>(m_ptr, m_refs);
  5. }
  6.                 
  7. template<typename T>
  8. sp<T>::sp(T* p, weakref_type* refs)
  9.     : m_ptr((p && refs->attemptIncStrong(this)) ? p : 0)
  10. {
  11. }
        是否能从弱指针生成一个强指针关键是看refs->attemptIncStrong,看其定义:

  1. bool RefBase::weakref_type::attemptIncStrong(const void* id)
  2. {
  3.     incWeak(id);
  4.                     
  5.     weakref_impl* const impl = static_cast<weakref_impl*>(this);
  6.                     
  7.     int32_t curCount = impl->mStrong;
  8.     LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",
  9.                this);
  10.     while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
  11.         if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
  12.             break;
  13.         }
  14.         curCount = impl->mStrong;
  15.     }
  16.                     
  17.     if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
  18.         bool allow;
  19.         if (curCount == INITIAL_STRONG_VALUE) {
  20.             // Attempting to acquire first strong reference... this is allowed
  21.             // if the object does NOT have a longer lifetime (meaning the
  22.             // implementation doesn
        首先通过incWeak将弱引用数加1(被强指针sp引用会导致强引用数和弱引用数同时加1),然后:

  1. int32_t curCount = impl->mStrong;
  2. while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
  3.     if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
  4.         break;
  5.     }
  6.     curCount = impl->mStrong;
  7. }

        如果之前已经有强引用,直接将强引用数加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:
  1. bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id)
  2. {
  3.     return (flags&FIRST_INC_STRONG) ? true : false;
  4. }
        如果curCount <= 0(只会等于0),表示对象强引用数经历了INITIAL_STRONG_VALUE -->大于0 --> 0,接下来就要判断:

  1. allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK
  2.     && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)
        如果对象的生命周期受强引用数控制,那么由于曾被sp引用过,现在强引用数又为0,对象就已经被delete了,所以就不能生成强引用, 否则如果对象的生命周期受弱引用数控制,就通过onIncStrongAttempted看类的实现者是否希望当对象的强引用数变为0时可以再次被强引用 引用。

  1. if (!allow) {
  2.     decWeak(id);
  3.     return false;
  4. }

    最后,如果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的值。

阅读(1252) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~