- 上一篇学习了轻量级指针,而这一篇则要把强指针与弱指针的原理都探个究竟。
- 关于智能指针的学习笔记,在这一篇也就完结了,总的来说内容是挺少的,不过其中有些逻辑还是需要细细琢磨才能理解的。
NOTE
- 参考源码版本:Android 7.1.2。
- 以下代码追踪思路均参考《Android 系统源代码情景分析(修订版)》。
强指针和弱指针
1. 强指针实现原理
1.1 RefBase.h
- 位置:
system/core/include/utils/RefBase.h
- 如果一个类对象要支持强弱指针,就必须继承
RefBase
类。
RefBase
类提供了强计数器与弱计数器。
Class RefBase
:
- 利用
weakref_impl
对象 mRefs
来描述对象的引用计数。
weakref_impl
继承自 RefBase
的内部类 weakref_type
。
incStrong
与 decStrong
仍为计数操作。
- 内部类
weakref_type
:
incWeak()
/ decWeak()
:弱引用计数操作。
attemptIncStrong()
/ attemptDecStrong()
:强引用计数操作。
class RefBase
{
public:
void incStrong(const void* id) const;
void decStrong(const void* id) const;
void forceIncStrong(const void* id) const;
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);
bool attemptIncWeak(const void* id);
int32_t getWeakCount() const;
void printRefs() const;
void trackMe(bool enable, bool retain);
};
weakref_type* createWeak(const void* id) const;
weakref_type* getWeakRefs() const;
inline void printRefs() const { getWeakRefs()->printRefs(); }
inline void trackMe(bool enable, bool retain)
{
getWeakRefs()->trackMe(enable, retain);
}
typedef RefBase basetype;
protected:
RefBase();
virtual ~RefBase();
enum {
OBJECT_LIFETIME_STRONG = 0x0000,
OBJECT_LIFETIME_WEAK = 0x0001,
OBJECT_LIFETIME_MASK = 0x0001
};
void extendObjectLifetime(int32_t mode);
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);
private:
friend class ReferenceMover;
static void renameRefs(size_t n, const ReferenceRenamer& renamer);
static void renameRefId(weakref_type* ref,
const void* old_id, const void* new_id);
static void renameRefId(RefBase* ref,
const void* old_id, const void* new_id);
weakref_impl* const mRefs;
};
1.2 RefBase.cpp
- 位置:
./system/core/libutils/RefBase.cpp
Class weakref_impl
:
- 注意宏定义
DEBUG_REFS
,它控制是否进入调试版本,我们只关注非调试。
- 继承自
RefBase::weakref_type
。
mStrong
描述强引用计数。
mWeak
描述弱引用计数。
mBase
指向所引用的对象地址。
mFlags
描述对象的生命周期控制方式:
OBJECT_LIFRTIME_STRONG
:只受强引用计数影响。
OBJECT_LIFETIME_WEAK
:同时受强弱计数影响。
OBJECT_LIFETIME_MASK
:似乎是用来做 &
操作,取最后一位。
- 注意后两个的值是一样的。
class RefBase::weakref_impl : public RefBase::weakref_type
{
public:
std::atomic<int32_t> mStrong;
std::atomic<int32_t> mWeak;
RefBase* const mBase;
std::atomic<int32_t> mFlags;
#if !DEBUG_REFS
weakref_impl(RefBase* base)
: mStrong(INITIAL_STRONG_VALUE)
, mWeak(0)
, mBase(base)
, mFlags(0)
{
}
void addStrongRef(const void* ) { }
void removeStrongRef(const void* ) { }
void renameStrongRefId(const