3. 强指针
强指针所使用的引用计数类为RefBase,它LightRefBase类要复杂多了,所以才称后者为轻量级的引用计数基类吧。我们先来看看RefBase类的实现,它定义在frameworks/base/include/utils/RefBase.h文件中:
- 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
- {
- public:
- RefBase* refBase() const;
- void incWeak(const void* id);
- void decWeak(const void* id);
- bool attemptIncStrong(const void* id);
- //! This is only safe if you have set OBJECT_LIFETIME_FOREVER.
- 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);
- }
- protected:
- RefBase();
- virtual ~RefBase();
- //! Flags for extendObjectLifetime()
- enum {
- OBJECT_LIFETIME_WEAK = 0x0001,
- OBJECT_LIFETIME_FOREVER = 0x0003
- };
- 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 weakref_type;
- class weakref_impl;
- RefBase(const RefBase& o);
- RefBase& operator=(const RefBase& o);
- weakref_impl* const mRefs;
- };
RefBase类和LightRefBase类一样,提供了incStrong和decStrong成员函数来操作它的引用计数器;而RefBase类与LightRefBase类最大的区别是,它不像LightRefBase类一样直接提供一个整型值(mutable volatile int32_t mCount)来维护对象的引用计数,前面我们说过,复杂的引用计数技术同时支持强引用计数和弱引用计数,在RefBase类中,这两种计数功能是通过其成员变量mRefs来提供的。
RefBase类的成员变量mRefs的类型为weakref_impl指针,它实现在frameworks/base/libs/utils/RefBase.cpp文件中:
- 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 addWeakRef(const void* /*id*/) { }
- void removeWeakRef(const void* /*id*/) { }
- void printRefs() const { }
- void trackMe(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("NEW weakref_impl %p for RefBase %p", this, base);
- }
- ~weakref_impl()
- {
- LOG_ALWAYS_FATAL_IF(!mRetain && mStrongRefs != NULL, "Strong references remain!");
- LOG_ALWAYS_FATAL_IF(!mRetain && mWeakRefs != NULL, "Weak references remain!");
- }
- void addStrongRef(const void* id)
- {
- addRef(&mStrongRefs, id, mStrong);
- }
- void removeStrongRef(const void* id)
- {
- if (!mRetain)
- removeRef(&mStrongRefs, id);
- else
- addRef(&mStrongRefs, id, -mStrong);
- }
- void addWeakRef(const void* id)
- {
- addRef(&mWeakRefs, id, mWeak);
- }
- void removeWeakRef(const void* id)
- {
- if (!mRetain)
- removeRef(&mWeakRefs, id);
- else
- addRef(&mWeakRefs, id, -mWeak);
- }
- void trackMe(bool track, bool retain)
- {
- mTrackEnabled = track;
- mRetain = retain;
- }
- ......
- private:
- struct ref_entry
- {
- ref_entry* next;
- const void* id;
- #if DEBUG_REFS_CALLSTACK_ENABLED
- CallStack stack;
- #endif
- int32_t ref;
- };
- void addRef(ref_entry** refs, const void* id, int32_t mRef)
- {
- if (mTrackEnabled) {
- AutoMutex _l(mMutex);
- ref_entry* ref = new ref_entry;
- // Reference count at the time of the snapshot, but before the
- // update. Positive value means we increment, negative--we
- // decrement the reference count.
- ref->ref = mRef;
- ref->id = id;
- #if DEBUG_REFS_CALLSTACK_ENABLED
- ref->stack.update(2);
- #endif
- ref->next = *refs;
- *refs = ref;
- }
- }
- void removeRef(ref_entry** refs, const void* id)
- {
- if (mTrackEnabled) {
- AutoMutex _l(mMutex);
- ref_entry* ref = *refs;
- while (ref != NULL) {
- if (ref->id == id) {
- *refs = ref->next;
- delete ref;
- return;
- }
- refs = &ref->next;
- ref = *refs;
- }
- LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p (weakref_type %p) that doesn't exist!",
- id, mBase, this);
- }
- }
- ......
- Mutex mMutex;
- ref_entry* mStrongRefs;
- ref_entry* mWeakRefs;
- bool mTrackEnabled;
- // Collect stack traces on addref and removeref, instead of deleting the stack references
- // on removeref that match the address ones.
- bool mRetain;
- ......
- #endif
- };
这个类看起来实现得很复杂,其实不然,这个类的实现可以分成两部分:
- #if !DEBUG_REFS
- ......
- #else
编译指令之间的这部分源代码是Release版本的源代码,它的成员函数都是空实现;
- #else
- ......
- #endif
编译指令之间的部分源代码是Debug版本的源代码,它的成员函数都是有实现的,实现这些函数的目的都是为了方便开发人员调试引用计数用的,除此之外,还在内部实现了一个结构体ref_entry:
- struct ref_entry
- {
- ref_entry* next;
- const void* id;
- #if DEBUG_REFS_CALLSTACK_ENABLED
- CallStack stack;
- #endif
- int32_t ref;
- };
这个结构体也是为了方便调试而使用的,我们可以不关注这部分用于调试的代码。
总的来说,weakref_impl类只要提供了以下四个成员变量来维护对象的引用计数:
- volatile int32_t mStrong;
- volatile int32_t mWeak;
- RefBase* const mBase;
- volatile int32_t mFlags;
其中mStrong和mWeak分别表示对象的强引用计数和弱引用计数;RefBase类包含了一个weakref_impl类指针mRefs,而这里的weakref_impl类也有一个成员变量mBase来指向它的宿主类RefBase;mFlags是一个标志位,它指示了维护对象引用计数所使用的策略,后面我们将会分析到,它的取值为0,或者以下的枚举值:
- //! Flags for extendObjectLifetime()
- 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是调试用的一个结构体,实际使用中可以不关注。