智能指针:强指针sp,弱指针wp,轻量级指针LightRefBase。
相关文件:RefBase.h,RefBase.cpp,StrongPointer.h(注:参考代码android 4.2.2)。
RefBase.h:定义了RefBase类定义,wp模板类定义和实现,以及LightRefBase类定义。
RefBase.cpp:定义了RefBase类实现以及RefBase的嵌套类weakref_type的实现。
StrongPointer.h:定义了sp模板类定义和实现。
RefBase类主要方法如下:void RefBase::incStrong(const void* id) const{weakref_impl* const refs = mRefs;refs->incWeak(id); // 增加一次弱引用计数refs->addStrongRef(id); // 空函数// 原子操作,增加一次强引用计数,返回的是refs->mStrong执行加1操作之前的值const int32_t c = android_atomic_inc(&refs->mStrong);ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);// 第一次执行,c的值为INITIAL_STRONG_V ALUEif (c != INITIAL_STRONG_V ALUE) {//从第二次开始执行后,此条件都成立,直接返回return;}// 执行操作,refs->mStrong + (-INITIAL_STRONG_V ALUE),第一次执行后强引用计数refs->mStrong值变为1android_atomic_add(-INITIAL_STRONG_V ALUE, &refs->mStrong);refs->mBase->onFirstRef(); //第一次执行会调用该方法,子类可以覆盖该方法。
}void RefBase::decStrong(const void* id) const{weakref_impl* const refs = mRefs;refs->removeStrongRef(id); // 空函数// 原子操作,强引用计数减1,返回的是执行减1操作之前的值const int32_t c = android_atomic_dec(&refs->mStrong);ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);if (c == 1) {refs->mBase->onLastStrongRef(id); // 子类可覆盖该方法// mFlags值缺省为0if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG){delete this;}}refs->decWeak(id); // 弱引用计数减1}void RefBase::forceIncStrong(const void* id) const{weakref_impl* const refs = mRefs;refs->incWeak(id); // 弱引用计数加1refs->addStrongRef(id); // 空函数const int32_t c = android_atomic_inc(&refs->mStrong); // 强引用计数加1ALOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow",refs);switch (c) {case INITIAL_STRONG_V ALUE:android_atomic_add(-INITIAL_STRONG_V ALUE, &refs->mStrong);// 强引用计数减INITIAL_STRONG_V ALUE// fall through...case 0:refs->mBase->onFirstRef();}}// 创建嵌套类对象RefBase::weakref_type* RefBase::createWeak(const void* id) const{mRefs->incWeak(id); // 弱引用计数加1return mRefs;}// 延长对象生命周期void RefBase::extendObjectLifetime(int32_t mode){android_atomic_or(mode, &mRefs->mFlags); // 修改mFlags的值为mode}// RefBase构造函数在实例化时,创建一个weakref_impl对象,并且将当前类对象的this指针作为参数传递给weakref_impl类构造函数,因此它们之间存在相互引用。
RefBase::RefBase(): mRefs(new weakref_impl(this)) {}RefBase::~RefBase(){if (mRefs->mStrong == INITIAL_STRONG_V ALUE) {delete mRefs;} else {if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) { if (mRefs->mWeak == 0) {delete mRefs;}}const_cast<weakref_impl*&>(mRefs) = NULL;}weakref_type类主要方法如下://由弱生强方法,例如A * pa =new A(); wp<A> wpa(pa); sp<A> spa = wpa.promote();bool RefBase::weakref_type::attemptIncStrong(const void* id){incWeak(id); // 弱引用计数加1weakref_impl* const impl = static_cast<weakref_impl*>(this);int32_t curCount = impl->mStrong; // 强引用计数,初始值为INITIAL_STRONG_V ALUE ALOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",this);// while循环表示多线程操作情况,将强引用计数加1while (curCount > 0 && curCount != INITIAL_STRONG_V ALUE) {if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) { break;}curCount = impl->mStrong;}if (curCount <= 0 || curCount == INITIAL_STRONG_V ALUE) {bool allow;// 判断是否可以增加强引用计数if (curCount == INITIAL_STRONG_V ALUE) {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);}// 若不能增加强引用计数,就执行弱引用计数减1,因为之前弱引用做过加1了。
if (!allow) {decWeak(id);return false;curCount = android_atomic_inc(&impl->mStrong); // 强引用计数加1if (curCount > 0 && curCount < INITIAL_STRONG_V ALUE) {impl->mBase->onLastStrongRef(id);}}impl->addStrongRef(id); // 空函数if (curCount == INITIAL_STRONG_V ALUE) {// 将impl->mStrong的值+ (-INITIAL_STRONG_V ALUE)android_atomic_add(-INITIAL_STRONG_V ALUE, &impl->mStrong);impl->mBase->onFirstRef(); // 第一次执行强引用计数加1,调用此方法}return true;}void RefBase::weakref_type::incWeak(const void* id){//基类指针转换为子类指针,weakref_impl为weakref_type的子类。
weakref_impl* const impl = static_cast<weakref_impl*>(this);impl->addWeakRef(id); //空函数const int32_t c = android_atomic_inc(&impl->mWeak); // 弱引用计数加1ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);}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); // 弱引用计数减1ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);if (c != 1) return;if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) { if (impl->mStrong == INITIAL_STRONG_V ALUE) {delete impl->mBase; //delete 实际对象} else {delete impl; //delete weakref_impl对象}} else {// less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}impl->mBase->onLastWeakRef(id);if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) { delete impl->mBase; //delete 实际对象}}}总结:wp和sp使用实例代码如下:{Class A : public RefBase{};A *p = new A;sp<A> pa(p);wp<A> pb(pa);}sp: 它是一个模板类,强指针,采用代理模式实现,控制实际对象(通过模板参数实例化)的生命周期结束。