在Android中,RefBase结合了sp和wp,实现了一套通过引用计数的方法来控制对象声明周期的方法。
RefBase的定义在/frameworks/base/include/utils/RefBase.h,实现在/frameworks/base/libs/utils/RefBase.cpp。
wp的定义在/frameworks/base/include/utils/RefBase.h,
sp的定义在/frameworks/base/include/utils/StrongPointer.h中。
1.weakref_impl
看看RefBase的构造方法:
RefBase::RefBase()
: mRefs(new weakref_impl(this))
{
}
方法体是空的,只是简单的给成员变量mRefs赋值。
mRefs在RefBase.h中的定义:weakref_impl* const mRefs;
继续看weakref_impl是什么。
weakref_impl在RefBase.h中只有一个private的声明,定义和实现都在RefBase.cpp中。
class RefBase::weakref_impl : public RefBase::weakref_type
{
......
}
weakref_impl又是派生自weakref_type。
构造方法:
weakref_impl(RefBase* base)
: mStrong(INITIAL_STRONG_VALUE) //volatile int32_t mStrong;
, mWeak(0) //volatile int32_t mWeak;
, mBase(base) //RefBase* const mBase;
, mFlags(0) //volatile int32_t mFlags;
{
}
mBase又保存了创建它的RefBase,表示它实际代表的对象。
假设有一个class A,创建了一个A后,会相应的创建一个weak_ref,而且weak_ref中的mBase保存着实际的对象A。
这么做有什么用呢?可以看到weak_ref中有两个int值,其实就是两个引用计数器,一个强引用,一个弱引用。
假设1:
class A: public RefBase{}
A* pA = new A;
sp<A> spA(pA);
wp<A> wpA(spA);
1.sp
下面来看看sp的定义。
sp是一个模板类,看看sp的构造方法。
template<typename T>
sp<T>::sp(const sp<T>& other)
: m_ptr(other.m_ptr) //这个m_ptr就是 T* m_ptr,就是一个T类型的指针
{
if (m_ptr) m_ptr->incStrong(this);
}
所以sp<A> spA(pA),语句的意思就是,创建一个sp对象,sp对象中成员变量指向A对象。
在sp的构造方法中,又调用了A->incStrong(this),这个incStrong方法从字面上就可以看出,是增加强引用的引用计数。
void RefBase::incStrong(const void* id) const
{
weakref_impl* const refs = mRefs; //取得weakref_impl引用
refs->incWeak(id); //增加强引用的同时,弱引用计数也增加
refs->addStrongRef(id); //release版本中,addStrongRef什么都不做
//refs->mString的初始值是INITIAL_STRONG_VALUE,android_atomic_inc将refs->mString加1
//返回的c为refs->mStrong的旧值INITIAL_STRONG_VALUE
const int32_t c = android_atomic_inc(&refs->mStrong);
......
//c的值为INITIAL_STRONG_VALUE,表示第一次创建强引用,否则直接返回
if (c != INITIAL_STRONG_VALUE)
//第一次强引用,会走到这里。
//android_atomic_add是原子加操作,refs->mStrong的值是INITIAL_STRONG_VALUE+1,
//然后加上-INITIAL_STRONG_VALUE,那么refs->mStrong的值就是1