安卓智能指针
2016-02-04 00:56
429 查看
为什么要安卓智能指针
在安卓系统中,为提高运行效率,其框架中间层很多是采用c++和c语言去实现的,在这实现过程,必定会应用不少地指针操作,同时c++和c不想Java那样有垃圾自动回收功能,因此会使程序员在某些操作常常遇到一些如下的问题:忘记指针初始化,这是指针在程序执行过程中,会随机指向某个地址,一旦这个地址是程序或系统核心部分,容易引起数据错误或系统崩溃等错误(这个问题很好解决,将指针默认设置为null。)。
new 对象之后没有及时delete:该对象占用的内存空间没有及时的回收,使得系统可用的内存空间越来越少,很有可能最终导致内存溢出,出现崩溃
野指针:ptr=new Object ,创建了一个对象Object,且指针ptr指向它,当Object使用结束之后也delete了,但是没有做的操作就是没有将ptr清空,这样ptr仍然指向了该Object对象的地址。结果在使用时ptr不为空,可以使用,但是此时Object对象已经delete了,Object所在的地址上的对象可能已经发生了变化,还用ptr访问的话就可能出现未知错误。
在C++语言中,我们可以通过手动释放对象的内存空间,但是对于指针操作来说,释放对象内存空间的同时,又得避免出现野指针的现象,因此控制程序在何时候释放一个对象内存就显得尤为重要了(虽然c++11也提供三种智能指针,但三种都存在一定局限性,不太符合安卓的使用,因此需要针对安卓来开发一套智能指针来管理对象)。根据这些特点我们可以通过
引用计数的方法来实现这目的。
引用计数实现:
我们可以让一个对象对应用它的指针进行统计,并且这个变量保存中这个对象中,当计数为0时,就通过
delete删除这个对象,那么怎么实现在指针赋值时候就统计引用呢?答案就是通过c++运算符重载的模式和c++析构函数来实现这目的,具体伪代码实现如下:
[code]//自定义智能指针 template <typename T> class SmartPointer { //初始化时将m_ptr设置为空,这样第一个问题就解决了 inline SmartPointer(): m_ptr(0){} //虚构函数 ~wp(); //重载赋值操作符 SmartPointer& operator = (T* other); private: T* m_ptr;//保存object对象的地址 } //重载赋值操作符的实现 SmartPointer<T> &SmartPointer<T>::operator=(T* other) { if(other!=null) { m_ptr=other;//指向该对象other other->incStrong();//other引用计数加一 } return *this; } //虚构函数的实现 wp<T>::~wp() { if(m_ptr) m_ptr-<decStrong(); } //被智能指针指向的对象要继承的父类实现 template <class T> class LightRefBase { public: inline LightRefBase():mCount(0){} inline void incStrong() const//引用计数加一 { android_atomic_inc(&mCount); } inline void decStrong() const//引用计数减一 { if(android_atomic_dec(&mCount)==1) { delete static_cast<const T*>(this);//如果没有被引用就直接删除该对象 } } private: mutable volatile int32_t mCount;//引用计数的个数 }
可以看出被智能指针引用的对象要继承于LightRefBase类,且智能指针SmartPointer是通过重载赋值操作符和虚构函数实现自动的管理对象引用计数,其关系如图所示:
以下是简单的使用代码:
[code]//假设Class是一个继承了LightRefBase的类,这里创建一个Class对象 Class class=new Class(); //定义一个指向Class对象的智能指针 SmartPointer <Class> sp;//由于里面已经对指针进行初始化,故这里不用初始化 //智能指向了class,故class里面的引用计数加一 sp=class; //释放智能指针对象同时引用计数会减一,如果引用计数刚好为零,则删除释放引用对象的内存 sp=NULL;//切记删除智能指针不要用delete sp
安卓智能指针
在android应用中,android实现了两种智能指针,分别是Strong Pointer(强指针,简称sp)和Weak Pointer(弱指针,简称wp),智能强指针一般来控制对象的强引用,而智能弱指针一般来控制两者对象互相引用等现象。强指针sp:
其实android sp实现原理和上面的Smart Pointer实现基本类似,都是直接对引用计数的加一或者减一。
源码实现:
[code]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); } template<typename T> template<typename U> sp<T>::sp(U* other) : m_ptr(other) { if (other) ((T*)other)->incStrong(this); } template<typename T> template<typename U> sp<T>::sp(const sp<U>& other) : m_ptr(other.m_ptr) { if (m_ptr) m_ptr->incStrong(this); } template<typename T> sp<T>::~sp() { if (m_ptr) m_ptr->decStrong(this); } //重载赋值操作 template<typename T> sp<T>& sp<T>::operator = (const sp<T>& other) { T* otherPtr(other.m_ptr); if (otherPtr) otherPtr->incStrong(this);//将被sp指针指向otherPtr对象的引用计数加1 if (m_ptr) m_ptr->decStrong(this);//被sp指向的原来对象m_ptr引用计数减一 m_ptr = otherPtr;//更改指针为指向otherPtr对象 return *this; } //与上面一样 template<typename T> sp<T>& sp<T>::operator = (T* other) { if (other) other->incStrong(this); if (m_ptr) m_ptr->decStrong(this); m_ptr = other; return *this; } template<typename T> template<typename U> sp<T>& sp<T>::operator = (const sp<U>& other) { T* otherPtr(other.m_ptr); if (otherPtr) otherPtr->incStrong(this); if (m_ptr) m_ptr->decStrong(this); m_ptr = otherPtr; return *this; } template<typename T> template<typename U> sp<T>& sp<T>::operator = (U* other) { if (other) ((T*)other)->incStrong(this); if (m_ptr) m_ptr->decStrong(this); m_ptr = other; return *this; } template<typename T> void sp<T>::force_set(T* other) { other->forceIncStrong(this); m_ptr = other; } template<typename T> //重新初始化指向对象的指针 void sp<T>::clear() { if (m_ptr) { m_ptr->decStrong(this); m_ptr = 0; } } template<typename T> void sp<T>::set_pointer(T* ptr) { m_ptr = ptr; } template <typename T> inline TextOutput& operator<<(TextOutput& to, const sp<T>& val) { return printStrongPointer(to, val.get()); } }; // namespace RSC };
不过要满足sp的对象,需要其对象继承类上面LightRefBase类,否则sp对其不到应用作用了。
弱指针wp:
再看wp弱引用,已经有了强引用,为什么还要用弱引用呢?假如现在又两个类:CDad,CChild,其代码如下:
[code]struct CDad { CChild *myChild; } Struct CChild { CDad *myDad; }
这种情况虽然少见,但也不是不会发生,这两者关系如图:
这样就处于死锁状态,两者都处于被需要状态,不能被释放,这个时候就出现了弱引用,具体做法:CDad使用强指针引用CChild对象,而CChild只能使用弱引用指向CDad。规定当强引用计数为0时,不管弱引用是否为0都要delete自己,一旦delete自己就能打破僵局,避免死锁的出现。
wp源码实现:
[code]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;//将wp转换为sp函数 // 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(>) COMPARE_WEAK(<) COMPARE_WEAK(<=) COMPARE_WEAK(>=) inline bool operator == (const wp<T>& o) const { return (m_ptr == o.m_ptr) && (m_refs == o.m_refs); } template<typename U> inline bool operator == (const wp<U>& o) const { return m_ptr == o.m_ptr; } inline bool operator > (const wp<T>& o) const { return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); } template<typename U> inline bool operator > (const wp<U>& o) const { return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); } inline bool operator < (const wp<T>& o) const { return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); } template<typename U> inline bool operator < (const wp<U>& o) const { return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); } //重载运算比较符 inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; } template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); } inline bool operator <= (const wp<T>& o) const { return !operator > (o); } template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); } inline bool operator >= (const wp<T>& 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;//指向weakref_type类型的对象 }; //传入一个符合条件的对象时,并赋值给m_ptr template<typename T> wp<T>::wp(T* other) : m_ptr(other) { if (other) m_refs = other->createWeak(this);//创建弱引用,其实就是后面说的weakref_impl对象 } //传入智能弱指针,并赋值给m_ptr和m_refs 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);//弱引用计数加1 } //传入智能强指针,并赋值给m_ptrg template<typename T> wp<T>::wp(const sp<T>& other) : m_ptr(other.m_ptr) { if (m_ptr) { m_refs = m_ptr->createWeak(this); } } //与上面一样 template<typename T> template<typename U> wp<T>::wp(U* other) : m_ptr(other) { if (other) m_refs = other->createWeak(this); } template<typename T> template<typename U> wp<T>::wp(const wp<U>& other) : m_ptr(other.m_ptr) { if (m_ptr) { m_refs = other.m_refs; m_refs->incWeak(this); } } template<typename T> template<typename U> wp<T>::wp(const sp<U>& other) : m_ptr(other.m_ptr) { if (m_ptr) { m_refs = m_ptr->createWeak(this); } } template<typename T> wp<T>::~wp() { if (m_ptr) m_refs->decWeak(this);//引用计数器减一 } //指向新的引用对象时 template<typename T> wp<T>& wp<T>::operator = (T* other) { //如果other为空,则弱引用计数初始化为0,并强引用也设为空 weakref_type* newRefs = other ? other->createWeak(this) : 0; if (m_ptr) m_refs->decWeak(this);//原来引用计数减一 m_ptr = other; m_refs = newRefs; return *this; } template<typename T> wp<T>& wp<T>::operator = (const wp<T>& other) { weakref_type* otherRefs(other.m_refs); T* otherPtr(other.m_ptr); if (otherPtr) otherRefs->incWeak(this); if (m_ptr) m_refs->decWeak(this); m_ptr = otherPtr; m_refs = otherRefs; return *this; } template<typename T> wp<T>& wp<T>::operator = (const sp<T>& other) { weakref_type* newRefs = other != NULL ? other->createWeak(this) : NULL; T* otherPtr(other.m_ptr); if (m_ptr) m_refs->decWeak(this); m_ptr = otherPtr; m_refs = newRefs; return *this; } template<typename T> template<typename U> wp<T>& wp<T>::operator = (U* other) { weakref_type* newRefs = other ? other->createWeak(this) : NULL; if (m_ptr) m_refs->decWeak(this); m_ptr = other; m_refs = newRefs; return *this; } template<typename T> template<typename U> wp<T>& wp<T>::operator = (const wp<U>& other) { weakref_type* otherRefs(other.m_refs); U* otherPtr(other.m_ptr); if (otherPtr) otherRefs->incWeak(this); if (m_ptr) m_refs->decWeak(this); m_ptr = otherPtr; m_refs = otherRefs; return *this; } template<typename T> template<typename U> wp<T>& wp<T>::operator = (const sp<U>& other) { weakref_type* newRefs = other != NULL ? other->createWeak(this) : NULL; U* otherPtr(other.m_ptr); if (m_ptr) m_refs->decWeak(this); m_ptr = otherPtr; m_refs = newRefs; return *this; } //设置强引用和弱引用 template<typename T> void wp<T>::set_object_and_refs(T* other, weakref_type* refs) { if (other) refs->incWeak(this);//新的弱引用计数器增一 if (m_ptr) m_refs->decWeak(this);//原来的弱引用计数器减一 m_ptr = other; m_refs = refs; } //将弱引用转换为强引用 template<typename T> sp<T> wp<T>::promote() const { sp<T> result; if (m_ptr && m_refs->attemptIncStrong(&result)) { result.set_pointer(m_ptr); } return result; } template<typename T> //重置 void wp<T>::clear() { if (m_ptr) { m_refs->decWeak(this); m_ptr = 0; } }
1 除了指向目标对象的m_ptr还有一个指向weakref_type类型的对象,weakref_type是用来管理wp的类,由weakref_impl子类实现。
2 一个的方法就是promote方法,可以将wp升级为sp。
3 这里的目标对象不再是sp中的LightRefBase,而是其父类RefBase,这个父类不仅仅需要处理sp的情况,还要处理wp的情况。
RefBase的源码实现:
[code]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 //嵌套类,wp中的m_refs就引用到这个类 { 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 = 0x0001//掩码 }; 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 ReferenceMover; static void moveReferences(void* d, void const* s, size_t n, const ReferenceConverterBase& caster); private: //定义友元类 friend class weakref_type; //弱引用的实现类 class weakref_impl; RefBase(const RefBase& o); RefBase& operator=(const RefBase& o); //指向弱引用变量 weakref_impl* const mRefs; }; RefBase::RefBase() : mRefs(new weakref_impl(this))//构造方法创建了weakref_impl对象 { } //虚构函数的具体实现 RefBase::~RefBase() { if (mRefs->mStrong == INITIAL_STRONG_VALUE) { // we never acquired a strong (and/or weak) reference on this object. delete mRefs; } else { // life-time of this object is extended to WEAK or FOREVER, in // which case weakref_impl doesn't out-live the object and we // can free it now. if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) { // It's possible that the weak count is not 0 if the object // re-acquired a weak reference in its destructor if (mRefs->mWeak == 0) { delete mRefs; } } } // for debugging purposes, clear this. const_cast<weakref_impl*&>(mRefs) = NULL; }
从源码可以知道,RefBase嵌套了weakref_type类,也就是wp维护该类型的一个字段 m_refs,但RefBase也维护一个weakref_impl类型的字段mRefs,从名字可以看出weakref_impl应该是weakref_type的类具体实现,其部分源码(system\core\libutils\RefBase.cpp)如下:
[code]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 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) { } #else weakref_impl(RefBase* base)//调试情况下 : mStrong(INITIAL_STRONG_VALUE)//强引用计数INITIAL_STRONG_VALUE 等于0x1000000 , mWeak(0)//弱引用计数初始化为0 , mBase(base)//保存传入的base值,就是目标对象 , mFlags(0)//保存生命周期标志,默认为Strong , mStrongRefs(NULL) , mWeakRefs(NULL) , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT) , mRetain(false) { } //析构函数 ~weakref_impl() { //打印出剩下的强引用信息 bool dumpStack = false; if (!mRetain && mStrongRefs != NULL) { dumpStack = true; ALOGE("Strong references remain:"); ref_entry* refs = mStrongRefs; while (refs) { char inc = refs->ref >= 0 ? '+' : '-'; // ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref); #if DEBUG_REFS_CALLSTACK_ENABLED refs->stack.log(LOG_TAG); #endif refs = refs->next; } } //打出剩下的弱引用信息 if (!mRetain && mWeakRefs != NULL) { dumpStack = true; ALOGE("Weak references remain!"); ref_entry* refs = mWeakRefs; //遍历打印引用链信息 while (refs) { char inc = refs->ref >= 0 ? '+' : '-'; //打印出当前对象还有多少弱引用 ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref); #if DEBUG_REFS_CALLSTACK_ENABLED refs->stack.log(LOG_TAG); #endif refs = refs->next; } } if (dumpStack) { ALOGE("above errors at:"); CallStack stack(LOG_TAG); } } }
从源码分析我们知道,强引用和若引用计数器在weakref_iml实现类中,而RefBase类中又维护其m_refs,其关系如图所示:
和LightRefBase不同,RefBase不是直接使用int变量来保存引用计数值,而是采用了weakref_type类型的计数器,这是用于RefBase要处理弱引用和强引用两种计数类型。另外,wp中也同时保存了这个计数器的地址,也就是wp中的m_refs和RefBase中的mRefs都指向了计数器,其中wp是通过在构造函数中调用目标对象的createWeak来获得计数器地址,而计数器本身是由RefBase在构造是创建的。
首先我们看RefBase中的
createWeak(),因为它的子类对象一旦复制给wp,就会在wp的构造函数调用
createWeak()付给弱引用,具体实现如下:
[code]RefBase::weakref_type* RefBase::createWeak(const void* id) const { mRefs->incWeak(id);//增加弱引用计数 return mRefs; }
从上面的方法知道在返回弱引用的同时,通过
incWeak()增加弱引用的计数,其具体实现:
[code]void RefBase::weakref_type::incWeak(const void* id) { weakref_impl* const impl = static_cast<weakref_impl*>(this);//获取保存这个对象的计数器的weakref_impl impl->addWeakRef(id);// const int32_t c __unused = android_atomic_inc(&impl->mWeak);//增加弱引用 ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);//打印出最后一个对该对象弱引用提示 }
相对于wp引用RefBase子类对象来说,sp引用RefBase子类对象会通过调用
incStrong方法来增加强引用计数值,其具体实现如下:
[code]void RefBase::incStrong(const void* id) const { weakref_impl* const refs = mRefs; refs->incWeak(id);//增加弱引用计数值 refs->addStrongRef(id););//调试使用,非调试没有具体操作 //增加强引用,并返回原来的值,其mStrong的值初始化为0x1000000,增加以后就是0x1000001 const int32_t c = android_atomic_inc(&refs->mStrong);//增加强引用计数值 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; } //进行相加操作,即相当于0x1000001-0x1000000=1 android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); //首次引用的回掉,此方法体默认为空,需自己去实现 refs->mBase->onFirstRef(); }
从其方法分析知道,当sp指向继承RefBase对象时,不仅强引用计数值增一,弱引用计数值也会增一。
既然有增加引用计数值得方法,那么一定也有减少引用计数值的方法,其那就是
decStrong()和
decWeak()两个方法,一个是减少强引用计数值,另一个是减少弱引用计数值,其
decStrong()具体实现如下:
[code]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 //打印对象被强引用的次数 ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c); #endif ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs); if (c == 1) { //回调此方法,此方法体也为空,需要子类实现 refs->mBase->onLastStrongRef(id); //进行掩码运算,判断是否为强引用 if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) { delete this;//删除对象 } } refs->decWeak(id);//并删除弱引用 }
结合上面两部分源码,我们发现一个规律,就是sp引用RefBase子类对象时,该子类对象调用
incStrong()或
decStrong()时,强引用和弱引用计数值要么都增一要么都减一,一一匹配。
其
decWeak()具体实现:
[code]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); ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this); //如果弱引用还不是最后一个,则返回 if (c != 1) return; //判断标记释放规则是否受强引用控制的,还是仅依赖弱引用 if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) { // This is the regular lifetime case. The object is destroyed // when the last strong reference goes away. Since weakref_impl // outlive the object, it is not destroyed in the dtor, and // we'll have to do it here. if (impl->mStrong == INITIAL_STRONG_VALUE) { // Special case: we never had a strong reference, so we need to // destroy the object now. //如果该对象从来没有被强引用,则用这种方式删除对象,否则用下面的方式删除 delete impl->mBase; } else { // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase); delete impl; } } else { // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER} impl->mBase->onLastWeakRef(id); if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) { // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference // is gone, we can destroy the object. delete impl->mBase; } } }
从上面部分看来
mFlags这个标记对智能指针管理对象有很大的影响,其默认值为0(即OBJECT_LIFETIME_STRONG),但可以通过下面来更改其引用控制规则:
[code]void RefBase::extendObjectLifetime(int32_t mode) { android_atomic_or(mode, &mRefs->mFlags);//or运算 }
使用安卓智能指针简单实例
定义一个符合被安卓智能指针可引用的类,具体代码如下:[code]//该类继承了RefBase class Test:public RefBase { } int main() { Test * test=new Test(); sp<Test> spTest(test);//强引用test对象,这是强引用计数值加一,弱引用计数值也加一,即mStrong=1,mWeak=1 wp<Test> wpTest(test);//弱引用test对象,这是只有弱引用计数值加一,即mStrong=1,mWeak=2 //下面不要通过delete指针对象方式释放对象,因为其sp和wp都通过重载了`=` 操作符来管理引用的 spTest=null;//这是mStrong=0,mWeak=1, 如果是test标记是为强引用控制,则释放该对象,但还没有释放内部weakref_impl对象 wpTest=null;//mWeak=0,释放了内部weakref_impl对象 }
总结:
安卓智能指针分为强指针sp和弱指针 wp两种。
一般来说目标对象的父类是RefBase,因为其存储了强引用和弱引用两种类型的计数值。
当sp引用目标对象时,强引用和弱引用计数值都会加一。
当wp引用目标对象时,只有弱引用计数值会加一。
使用者可以通过extendObjectLifetime()方法来更改智能指针管理对象的规则,不同规则下对删除目标对象的时机判断也是不一样的。
参考资料:
http://blog.csdn.net/yujun411522/article/details/46624583#
相关文章推荐
- overridePendingTransition
- spring IOC的理解
- 【Redis test】You need tcl 8.5 or newer in order to run the Redis test
- 两个任意长度的长整数相乘(C语言、双向链表方法)
- Android开发刷新相册问题!!
- WordPress优化:修改文章标签为彩色标签
- [html5]动态多边形flat-surface-shader
- 快过年了
- CentOS6.5下修改MySQL编码方法
- [LeetCode]162. Find Peak Element
- swap file "*.swp" already exists!的解决方法
- 自定义控件中如何实现按钮之间的共轭?
- 51Nod 1046 A^B Mod C(快速幂)
- 【Linux】SVN的安装和配置
- sqlserver重置标识
- category和extension
- strace命令入门
- java深入理解反射机制
- 【jQuery基础学习】09 jQuery与前端(这章很水)
- 《Netty in Action V5》-- 第1章 Netty与Java NIO APIS