Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析(2)
3. 强指针 强指针所使用的引用计数类为RefBase,它LightRefBase类要复杂多了,所以才称后者为轻量级的引用计数基类吧。我们先来看看RefBase类的实现,它定义在frameworks/base/include/utils/RefBase.h文件中: classRefBase { public: voidincStrong(constvoid*id)const; voiddecStrong(constvoid*id)const; voidforceIncStrong(constvoid*id)const; //!DEBUGGINGONLY:Getcurrentstrongrefcount. int32_tgetStrongCount()const; classweakref_type { public: RefBase*refBase()const; voidincWeak(constvoid*id); voiddecWeak(constvoid*id); boolattemptIncStrong(constvoid*id); //!ThisisonlysafeifyouhavesetOBJECT_LIFETIME_FOREVER. boolattemptIncWeak(constvoid*id); //!DEBUGGINGONLY:Getcurrentweakrefcount. int32_tgetWeakCount()const; //!DEBUGGINGONLY:Printreferencesheldonobject. voidprintRefs()const; //!DEBUGGINGONLY:Enabletrackingforthisobject. //enable--enable/disabletracking //retain--whentrackingisenable,iftrue,thenwesaveastacktrace //foreachreferenceanddereference;whenretain==false,we //matchupreferencesanddereferencesandkeeponlythe //outstandingones. voidtrackMe(boolenable,boolretain); }; weakref_type*createWeak(constvoid*id)const; weakref_type*getWeakRefs()const; //!DEBUGGINGONLY:Printreferencesheldonobject. inlinevoidprintRefs()const{getWeakRefs()->printRefs();} //!DEBUGGINGONLY:Enabletrackingofobject. inlinevoidtrackMe(boolenable,boolretain) { getWeakRefs()->trackMe(enable,retain); } protected: RefBase(); virtual~RefBase(); //!FlagsforextendObjectLifetime() enum{ OBJECT_LIFETIME_WEAK=0x0001, OBJECT_LIFETIME_FOREVER=0x0003 }; voidextendObjectLifetime(int32_tmode); //!FlagsforonIncStrongAttempted() enum{ FIRST_INC_STRONG=0x0001 }; virtualvoidonFirstRef(); virtualvoidonLastStrongRef(constvoid*id); virtualboolonIncStrongAttempted(uint32_tflags,constvoid*id); virtualvoidonLastWeakRef(constvoid*id); private: friendclassweakref_type; classweakref_impl; RefBase(constRefBase&o); RefBase&operator=(constRefBase&o); weakref_impl*constmRefs; }; RefBase类和LightRefBase类一样,提供了incStrong和decStrong成员函数来操作它的引用计数器;而RefBase类与LightRefBase类最大的区别是,它不像LightRefBase类一样直接提供一个整型值(mutable volatile int32_t mCount)来维护对象的引用计数,前面我们说过,复杂的引用计数技术同时支持强引用计数和弱引用计数,在RefBase类中,这两种计数功能是通过其成员变量mRefs来提供的。 RefBase类的成员变量mRefs的类型为weakref_impl指针,它实现在frameworks/base/libs/utils/RefBase.cpp文件中: classRefBase::weakref_impl:publicRefBase::weakref_type { public: volatileint32_tmStrong; volatileint32_tmWeak; RefBase*constmBase; volatileint32_tmFlags; #if!DEBUG_REFS weakref_impl(RefBase*base) :mStrong(INITIAL_STRONG_VALUE) ,mWeak(0) ,mBase(base) ,mFlags(0) { } voidaddStrongRef(constvoid*/*id*/){} voidremoveStrongRef(constvoid*/*id*/){} voidaddWeakRef(constvoid*/*id*/){} voidremoveWeakRef(constvoid*/*id*/){} voidprintRefs()const{} voidtrackMe(bool,bool){} #else weakref_impl(RefBase*base) :mStrong(INITIAL_STRONG_VALUE) ,mWeak(0) ,mBase(base) ,mFlags(0) ,mStrongRefs(NULL) ,mWeakRefs(NULL) ,mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT) ,mRetain(false) { //LOGI("NEWweakref_impl%pforRefBase%p",this,base); } ~weakref_impl() { LOG_ALWAYS_FATAL_IF(!mRetain&&mStrongRefs!=NULL,"Strongreferencesremain!"); LOG_ALWAYS_FATAL_IF(!mRetain&&mWeakRefs!=NULL,"Weakreferencesremain!"); } voidaddStrongRef(constvoid*id) { addRef(&mStrongRefs,id,mStrong); } voidremoveStrongRef(constvoid*id) { if(!mRetain) removeRef(&mStrongRefs,id); else addRef(&mStrongRefs,id,-mStrong); } voidaddWeakRef(constvoid*id) { addRef(&mWeakRefs,id,mWeak); } voidremoveWeakRef(constvoid*id) { if(!mRetain) removeRef(&mWeakRefs,id); else addRef(&mWeakRefs,id,-mWeak); } voidtrackMe(booltrack,boolretain) { mTrackEnabled=track; mRetain=retain; } ...... private: structref_entry { ref_entry*next; constvoid*id; #ifDEBUG_REFS_CALLSTACK_ENABLED CallStackstack; #endif int32_tref; }; voidaddRef(ref_entry**refs,constvoid*id,int32_tmRef) { if(mTrackEnabled){ AutoMutex_l(mMutex); ref_entry*ref=newref_entry; //Referencecountatthetimeofthesnapshot,butbeforethe //update.Positivevaluemeansweincrement,negative--we //decrementthereferencecount. ref->ref=mRef; ref->id=id; #ifDEBUG_REFS_CALLSTACK_ENABLED ref->stack.update(2); #endif ref->next=*refs; *refs=ref; } } voidremoveRef(ref_entry**refs,constvoid*id) { if(mTrackEnabled){ AutoMutex_l(mMutex); ref_entry*ref=*refs; while(ref!=NULL){ if(ref->id==id){ *refs=ref->next; deleteref; return; } refs=&ref->next; ref=*refs; } LOG_ALWAYS_FATAL("RefBase:removingid%ponRefBase%p(weakref_type%p)thatdoesn'texist!", id,mBase,this); } } ...... MutexmMutex; ref_entry*mStrongRefs; ref_entry*mWeakRefs; boolmTrackEnabled; //Collectstacktracesonaddrefandremoveref,insteadofdeletingthestackreferences //onremoverefthatmatchtheaddressones. boolmRetain; ...... #endif }; 这个类看起来实现得很复杂,其实不然,这个类的实现可以分成两部分: #if!DEBUG_REFS ...... #else 编译指令之间的这部分源代码是Release版本的源代码,它的成员函数都是空实现; #else ...... #endif 编译指令之间的部分源代码是Debug版本的源代码,它的成员函数都是有实现的,实现这些函数的目的都是为了方便开发人员调试引用计数用的,除此之外,还在内部实现了一个结构体ref_entry: structref_entry { ref_entry*next; constvoid*id; #ifDEBUG_REFS_CALLSTACK_ENABLED CallStackstack; #endif int32_tref; }; 这个结构体也是为了方便调试而使用的,我们可以不关注这部分用于调试的代码。 总的来说,weakref_impl类只要提供了以下四个成员变量来维护对象的引用计数: volatileint32_tmStrong; volatileint32_tmWeak; RefBase*constmBase; volatileint32_tmFlags; 其中mStrong和mWeak分别表示对象的强引用计数和弱引用计数;RefBase类包含了一个weakref_impl类指针mRefs,而这里的weakref_impl类也有一个成员变量mBase来指向它的宿主类RefBase;mFlags是一个标志位,它指示了维护对象引用计数所使用的策略,后面我们将会分析到,它的取值为0,或者以下的枚举值: //!FlagsforextendObjectLifetime() enum{ OBJECT_LIFETIME_WEAK=0x0001, OBJECT_LIFETIME_FOREVER=0x0003 }; 这里我们还需要注意的一点的是,从weakref_impl的类名来看,它应该是一个实现类,那么,就必然有一个对应的接口类,这个对应的接口类的就是RefBase类内部定义的weakref_type类了,这是一种把类的实现与接口定义分离的设计方法。学习过设计模式的读者应该知道,在设计模式里面,非常强调类的接口定义和类的实现分离,以便利于后续扩展和维护,这里就是用到了这种设计思想。 说了这多,RefBase类给人的感觉还是挺复杂的,不要紧,我们一步步来,先通过下面这个图来梳理一下这些类之间的关系: 从这个类图可以看出,每一个RefBase对象包含了一个weakref_impl对象,而weakref_impl对象实现了weakref_type接口,同时它可以包含多个ref_entry对象,前面说过,ref_entry是调试用的一个结构体,实际使用中可以不关注。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966559,如需转载请自行联系原作者