西西軟件下載最安全的下載網(wǎng)站、值得信賴(lài)的軟件下載站!

首頁(yè)編程開(kāi)發(fā)Android → Android指針管理:RefBase,SP,WP、通過(guò)引用計(jì)數(shù)來(lái)實(shí)現(xiàn)智能指針

Android指針管理:RefBase,SP,WP、通過(guò)引用計(jì)數(shù)來(lái)實(shí)現(xiàn)智能指針

相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來(lái)源:AngelDevil時(shí)間:2013/3/10 12:54:05字體大。A-A+

作者:AngelDevil點(diǎn)擊:0次評(píng)論:0次標(biāo)簽: 指針

  • 類(lèi)型:系統(tǒng)優(yōu)化大小:76M語(yǔ)言:中文 評(píng)分:6.0
  • 標(biāo)簽:
立即下載

Android中通過(guò)引用計(jì)數(shù)來(lái)實(shí)現(xiàn)智能指針,并且實(shí)現(xiàn)有強(qiáng)指針與弱指針。由對(duì)象本身來(lái)提供引用計(jì)數(shù)器,但是對(duì)象不會(huì)去維護(hù)引用計(jì)數(shù)器的值,而是由智能指針來(lái)管理。

要達(dá)到所有對(duì)象都可用引用計(jì)數(shù)器實(shí)現(xiàn)智能指針管理的目標(biāo),可以定義一個(gè)公共類(lèi),提供引用計(jì)數(shù)的方法,所有對(duì)象都去繼承這個(gè)公共類(lèi),這樣就可以實(shí)現(xiàn)所有對(duì)象都可以用引用計(jì)數(shù)來(lái)管理的目標(biāo),在Android中,這個(gè)公共類(lèi)就是RefBase,同時(shí)還有一個(gè)簡(jiǎn)單版本LightRefBase。

RefBase作為公共基類(lèi)提供了引用計(jì)數(shù)的方法,但是并不去維護(hù)引用計(jì)數(shù)的值,而是由兩個(gè)智能指針來(lái)進(jìn)行管理:sp(Strong Pointer)和wp(Weak Pointer),代表強(qiáng)引用計(jì)數(shù)和弱引用計(jì)數(shù)。

一、輕量級(jí)引用計(jì)數(shù)的實(shí)現(xiàn):LightRefBase

template <class T>
class LightRefBase
{
public:
inline LightRefBase() : mCount(0) { }
inline void incStrong(const void* id) const {
android_atomic_inc(&mCount);
}
inline void decStrong(const void* id) const {
if (android_atomic_dec(&mCount) == 1) {
delete static_cast<const T*>(this);
}
}
//! DEBUGGING ONLY: Get current strong ref count.
inline int32_t getStrongCount() const {
return mCount;
}
typedef LightRefBase<T> basetype;
protected:
inline ~LightRefBase() { }
private:
mutable volatile int32_t mCount;
};
LightRefBase的實(shí)現(xiàn)很簡(jiǎn)單,只是內(nèi)部保存了一個(gè)變量用于保存對(duì)象被引用的次數(shù),并提供了兩個(gè)函數(shù)用于增加或減少引用計(jì)數(shù)。

二、sp(Strong Pointer)

LightRefBase僅僅提供了引用計(jì)數(shù)的方法,具體引用數(shù)應(yīng)該怎么管理,就要通過(guò)智能指針類(lèi)來(lái)管理了,每當(dāng)有一個(gè)智能指針指向?qū)ο髸r(shí),對(duì)象的引用計(jì)數(shù)要加1,當(dāng)一個(gè)智能指針取消指向?qū)ο髸r(shí),對(duì)象的引用計(jì)數(shù)要減1,在C++中,當(dāng)一個(gè)對(duì)象生成和銷(xiāo)毀時(shí)會(huì)自動(dòng)調(diào)用(拷貝)構(gòu)造函數(shù)和析構(gòu)函數(shù),所以,對(duì)對(duì)象引用數(shù)的管理就可以放到智能指針的(拷貝)構(gòu)造函數(shù)和析構(gòu)函數(shù)中。Android提供了一個(gè)智能指針可以配合LightRefBase使用:sp,sp的定義如下:

template <typename T>
class sp
{
public:
inline sp() : m_ptr(0) { }
sp(T* other);
sp(const sp<T>& other);

template<typename U> sp(U* other);
template<typename U> sp(const sp<U>& other);

~sp();

// Assignment
sp& operator = (T* other);
sp& operator = (const sp<T>& other);

template<typename U> sp& operator = (const sp<U>& other);
template<typename U> sp& operator = (U* other);

//! Special optimization for use by ProcessState (and nobody else).
void force_set(T* other);

// Reset
void clear();

// Accessors
inline T& operator* () const { return *m_ptr; }
inline T* operator-> () const { return m_ptr; }
inline T* get() const { return m_ptr; }

// Operators
COMPARE(==)
COMPARE(!=)
COMPARE(>)
COMPARE(<)
COMPARE(<=)
COMPARE(>=)
private:
template<typename Y> friend class sp;
template<typename Y> friend class wp;
void set_pointer(T* ptr);
T* m_ptr;
};

代碼比較多,其中Accessors部分代碼重載了*、->操作符使我們使用sp的時(shí)候就像使用真實(shí)的對(duì)象指針一樣,可以直接操作對(duì)象的屬性或方法,COMPARE是宏定義,用于重載關(guān)系操作符,由于對(duì)引用計(jì)數(shù)的控制主要是由(拷貝)構(gòu)造函數(shù)和析構(gòu)函數(shù)控制,所以忽略其他相關(guān)代碼后,sp可以精簡(jiǎn)為如下形式(賦值操作符也省略掉了,構(gòu)造函數(shù)省略相似的兩個(gè)):

template <typename T>
class sp
{
public:
inline sp() : m_ptr(0) { }
sp(T* other);
sp(const sp<T>& other);

~sp();

private:
template<typename Y> friend class sp;
template<typename Y> friend class wp;
void set_pointer(T* ptr);
T* m_ptr;
};
默認(rèn)構(gòu)造函數(shù)使智能指針不指向任何對(duì)象,sp(T* other)與sp(const sp<T>& other)的實(shí)現(xiàn)如下:

template<typename T>
sp<T>::sp(T* other)
: m_ptr(other)
{
if (other) other->incStrong(this);
}

template<typename T>
sp<T>::sp(const sp<T>& other)
: m_ptr(other.m_ptr)
{
if (m_ptr) m_ptr->incStrong(this);
}

內(nèi)部變量m_ptr指向?qū)嶋H對(duì)象,并調(diào)用實(shí)際對(duì)象的incStrong函數(shù),T繼承自L(fǎng)ightRefBase,所以此處調(diào)用的是LightRefBase的incStrong函數(shù),之后實(shí)際對(duì)象的引用計(jì)數(shù)加1。

當(dāng)智能指針?shù)N毀的時(shí)候調(diào)用智能指針的析構(gòu)函數(shù):

template<typename T>
sp<T>::~sp()
{
if (m_ptr) m_ptr->decStrong(this);
}
調(diào)用實(shí)際對(duì)象即LightRefBase的decStrong函數(shù),其實(shí)現(xiàn)如下:

inline void decStrong(const void* id) const {
if (android_atomic_dec(&mCount) == 1) {
delete static_cast<const T*>(this);
}
}
android_atomic_dec返回mCount減1之前的值,如果返回1表示這次減過(guò)之后引用計(jì)數(shù)就是0了,就把對(duì)象delete掉。

三、RefBase

RefBase提供了更強(qiáng)大的引用計(jì)數(shù)的管理。

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);
// acquires a strong reference if there is already one.
bool attemptIncStrong(const void* id);
// acquires a weak reference if there is already one.
// This is not always safe. see ProcessState.cpp and BpBinder.cpp
// for proper use.
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);
}
typedef RefBase basetype;

protected:
RefBase();
virtual ~RefBase();

//! Flags for extendObjectLifetime()
enum {
OBJECT_LIFETIME_STRONG = 0x0000,
OBJECT_LIFETIME_WEAK = 0x0001,
OBJECT_LIFETIME_MASK = 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;
};


不同于LightRefBase的是,RefBase內(nèi)部并沒(méi)有使用一個(gè)變量來(lái)維護(hù)引用計(jì)數(shù),而是通過(guò)一個(gè)weakref_impl *類(lèi)型的成員來(lái)維護(hù)引用計(jì)數(shù),并且同時(shí)提供了強(qiáng)引用計(jì)數(shù)和弱引用計(jì)數(shù)。weakreef_impl繼承于RefBase::weakref_type,代碼比較多,不過(guò)大都是調(diào)試代碼,由宏定義分開(kāi),Release是不包含高度代碼的,去除這些代碼后其定義為:

#define INITIAL_STRONG_VALUE (1<<28)

class RefBase::weakref_impl : public RefBase::weakref_type
{
public:
volatile int32_t mStrong;
volatile int32_t mWeak;
RefBase* const mBase;
volatile int32_t mFlags;

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) { }
};
weakref_impl中的函數(shù)都是作為調(diào)試用,Release版的實(shí)現(xiàn)都是空的,成員變量分別表示強(qiáng)引用數(shù)、弱引用數(shù)、指向?qū)嶋H對(duì)象的指針與flag,flag可控制實(shí)際對(duì)象的生命周期,取值為0或RefBase中定義的枚舉值。

RefBase提供了incStrong與decStrong函數(shù)用于控制強(qiáng)引用計(jì)數(shù)值,其弱引用計(jì)數(shù)值是由weakref_impl控制,強(qiáng)引用計(jì)數(shù)與弱引用數(shù)都保存在weakref_impl *類(lèi)型的成員變量mRefs中。

RefBase同LightRefBase一樣為對(duì)象提供了引用計(jì)數(shù)的方法,對(duì)引用計(jì)數(shù)的管理同樣要由智能指針控制,由于RefBase同時(shí)實(shí)現(xiàn)了強(qiáng)引用計(jì)數(shù)與弱引用計(jì)數(shù),所以就有兩種類(lèi)型的智能指針,sp(Strong Pointer)與wp(Weak Pointer)。

sp前面已經(jīng)說(shuō)過(guò),其(拷貝)構(gòu)造函數(shù)調(diào)用對(duì)象即RefBase的incStrong函數(shù)

void RefBase::incStrong(const void* id) const
{
weakref_impl* const refs = mRefs;
refs->incWeak(id);
refs->addStrongRef(id);
const int32_t c = android_atomic_inc(&refs->mStrong);
LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
if (c != INITIAL_STRONG_VALUE) {
return;
}
android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
refs->mBase->onFirstRef();
}
addStrong的函數(shù)體為空,incStrong函數(shù)內(nèi)部首先調(diào)用成員變量mRefs的incWeak函數(shù)將弱引用數(shù)加1,然后再將強(qiáng)引用數(shù)加1,由于android_atomic_inc返回變量的舊值,所以如果其不等于INITIAL_STRONG_VALUE就直接返回,則則是第一次由強(qiáng)智能指針(sp)引用,將其減去INITIAL_STRONG_VALUE后變成1,然后調(diào)用對(duì)象的onFirstRef。

成員變量mRefs是在對(duì)象的構(gòu)造函數(shù)中初始化的:

RefBase::RefBase()
: mRefs(new weakref_impl(this))
{
}
weakrel_impl的incWeak繼承自父類(lèi)weakrel_type的incWeak:

void RefBase::weakref_type::incWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>
impl->addWeakRef(id);
const int32_t c = android_atomic_inc(&impl->mWeak);
LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
}
addWeakRef實(shí)現(xiàn)同樣為空,所以只是將弱引用計(jì)數(shù)加1。所以當(dāng)對(duì)象被sp引用后,強(qiáng)引用計(jì)數(shù)與弱引用計(jì)數(shù)會(huì)同時(shí)加1。

當(dāng)sp銷(xiāo)毀時(shí)其析構(gòu)函數(shù)調(diào)用對(duì)象即RefBase的decStrong函數(shù):

void RefBase::decStrong(const void* id) const
{
weakref_impl* const refs = mRefs;
refs->removeStrongRef(id);
const int32_t c = android_atomic_dec(&refs->mStrong);
if (c == 1) {
const_cast<RefBase*>(this)->onLastStrongRef(id);
if ((refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
delete this;
}
}
refs->removeWeakRef(id);
refs->decWeak(id);
}
decStrong中將強(qiáng)引用數(shù)與弱引用數(shù)同時(shí)減1,如果這是最后一個(gè)強(qiáng)引用的話(huà),會(huì)調(diào)用對(duì)象的onLastStrongRef,并且判斷成員變量mRefs的成員變量mFlags來(lái)決定是否在對(duì)象的強(qiáng)引用數(shù)為0時(shí)釋放對(duì)象。

mFlags可以為0或以下兩個(gè)枚舉值:

enum {
OBJECT_LIFETIME_WEAK = 0x0001,
OBJECT_LIFETIME_FOREVER = 0x0003
};
mFlags的值可以通過(guò)extendObjectLifetime函數(shù)改變:

1
2
3
4
void RefBase::extendObjectLifetime(int32_t mode)
{
android_atomic_or(mode, &mRefs->mFlags);
}
OBJECT_LIFETIME_FOREVER包含OBJECT_LIFETIME_WEAK(位運(yùn)算中其二進(jìn)制11包含01),所以當(dāng)

refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
為true時(shí)表示mFlags為0,實(shí)際對(duì)象的生命周期受強(qiáng)引用數(shù)控制,所以在強(qiáng)引用數(shù)為0時(shí)delete this,否則實(shí)際對(duì)象的生命周期就由弱引用數(shù)控制。

再來(lái)看decWeak:

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);
if (c != 1) return;

if ((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
if (impl->mStrong == INITIAL_STRONG_VALUE)
delete impl->mBase;
else {
delete impl;
}
} else {
impl->mBase->onLastWeakRef(id);
if ((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) {
delete impl->mBase;
}
}
}
將弱引用數(shù)減1,若減1后不為0直接返回,否則判斷

(impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
判斷結(jié)果為true:

實(shí)際對(duì)象生命周期被強(qiáng)引用數(shù)控制,接下來(lái)判斷:

mpl->mStrong == INITIAL_STRONG_VALUE
如果判斷為true表示對(duì)象只被弱引用引用過(guò),現(xiàn)在弱引用數(shù)為0,直接刪除實(shí)際對(duì)象。

如果判斷為false,表示對(duì)象曾經(jīng)被強(qiáng)引用引用過(guò),但現(xiàn)在強(qiáng)引用為變?yōu)?了(因?yàn)樵黾踊驕p小強(qiáng)引用數(shù)時(shí)一定同時(shí)增加或減小弱引用數(shù),所以弱引用數(shù)為0時(shí),強(qiáng)引用數(shù)一定為0),弱引用數(shù)為0了,直接釋放mRefs,而實(shí)際對(duì)象由于受強(qiáng)引用數(shù)控制,已經(jīng)在RefBase::decStrong中被delete了。

判斷結(jié)果為false:

判斷mFlgs是否是OBJECT_LIFETIME_FOREVER,如果是,什么都不作由用戶(hù)自己控制對(duì)象的生命周期,否則,實(shí)際對(duì)象的生命周期受弱引用數(shù)控制,現(xiàn)在弱引用數(shù)為0,delete實(shí)際對(duì)象。

四、wp(Weak Pointer)

定義如下:

template <typename T>
class wp
{
public:
typedef typename RefBase::weakref_type weakref_type;

inline wp() : m_ptr(0) { }

wp(T* other);
wp(const wp<T>& other);
wp(const sp<T>& other);
template<typename U> wp(U* other);
template<typename U> wp(const sp<U>& other);
template<typename U> wp(const wp<U>& other);

~wp();

// Assignment

wp& operator = (T* other);
wp& operator = (const wp<T>& other);
wp& operator = (const sp<T>& other);

template<typename U> wp& operator = (U* other);
template<typename U> wp& operator = (const wp<U>& other);
template<typename U> wp& operator = (const sp<U>& other);

void set_object_and_refs(T* other, weakref_type* refs);

// promotion to sp

sp<T> promote() const;

// Reset

void clear();

// Accessors

inline weakref_type* get_refs() const { return m_refs; }

inline T* unsafe_get() const { return m_ptr; }

// Operators

COMPARE(==)
COMPARE(!=)
COMPARE(>)
COMPARE(<)
COMPARE(<=)
COMPARE(>=)

private:
template<typename Y> friend class sp;
template<typename Y> friend class wp;

T* m_ptr;
weakref_type* m_refs;
};
同sp一樣,m_ptr指向?qū)嶋H對(duì)象,但wp還有一個(gè)成員變量m_refs。

template<typename T>
wp<T>::wp(T* other)
: m_ptr(other)
{
if (other) m_refs = other->createWeak(this);
}

template<typename T>
wp<T>::wp(const wp<T>& other)
: m_ptr(other.m_ptr), m_refs(other.m_refs)
{
if (m_ptr) m_refs->incWeak(this);
}

RefBase::weakref_type* RefBase::createWeak(const void* id) const
{
mRefs->incWeak(id);
return mRefs;
}
可以看到,wp的m_refs就是RefBase即實(shí)際對(duì)象的mRefs。

wp析構(gòu)的時(shí)候減少弱引用計(jì)數(shù):

template<typename T>
wp<T>::~wp()
{
if (m_ptr) m_refs->decWeak(this);
}
由于弱指針沒(méi)有重載*與->操作符,所以不能直接操作指向的對(duì)象,雖然有unsafe_get函數(shù),但像名字所示的,不建議使用,直接使用實(shí)際對(duì)象指針的話(huà)就沒(méi)必要用智能指針了。

因?yàn)槿踔羔槻荒苤苯硬僮鲗?duì)象,所以要想操作對(duì)象的話(huà)就要將其轉(zhuǎn)換為強(qiáng)指針,即wp::promote方法:

template<typename T>
sp<T> wp<T>::promote() const
{
return sp<T>(m_ptr, m_refs);
}

template<typename T>
sp<T>::sp(T* p, weakref_type* refs)
: m_ptr((p && refs->attemptIncStrong(this)) ? p : 0)
{
}
是否能從弱指針生成一個(gè)強(qiáng)指針關(guān)鍵是看refs->attemptIncStrong,看其定義:

bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
incWeak(id);

weakref_impl* const impl = static_cast<weakref_impl*>(this);

int32_t curCount = impl->mStrong;
LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",
this);
while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
break;
}
curCount = impl->mStrong;
}

if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
bool allow;
if (curCount == INITIAL_STRONG_VALUE) {
// Attempting to acquire first strong reference... this is allowed
// if the object does NOT have a longer lifetime (meaning the
// implementation doesn't need to see this), or if the implementation
// allows it to happen.
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);
}
if (!allow) {
decWeak(id);
return false;
}
curCount = android_atomic_inc(&impl->mStrong);

// If the strong reference count has already been incremented by
// someone else, the implementor of onIncStrongAttempted() is holding
// an unneeded reference. So call onLastStrongRef() here to remove it.
// (No, this is not pretty.) Note that we MUST NOT do this if we
// are in fact acquiring the first reference.
if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
impl->mBase->onLastStrongRef(id);
}
}

impl->addWeakRef(id);
impl->addStrongRef(id);

#if PRINT_REFS
LOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
#endif

if (curCount == INITIAL_STRONG_VALUE) {
android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);
impl->mBase->onFirstRef();
}

return true;
}
首先通過(guò)incWeak將弱引用數(shù)加1(被強(qiáng)指針sp引用會(huì)導(dǎo)致強(qiáng)引用數(shù)和弱引用數(shù)同時(shí)加1),然后:

int32_t curCount = impl->mStrong;
while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
break;
}
curCount = impl->mStrong;
}
如果之前已經(jīng)有強(qiáng)引用,直接將強(qiáng)引用數(shù)加1,android_atomic_cmpxchg表示如果impl->mStrong的值為curCount,則把impl->mString的值改為curCount+1,此處用while循環(huán)是防止其他線(xiàn)程已經(jīng)增加了強(qiáng)引用數(shù)。

接下來(lái):

if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE)
表示對(duì)象目前沒(méi)有強(qiáng)引用,這就要判斷對(duì)象是否存在了。

如果curCount == INITIAL_STRONG_VALUE,表示對(duì)象沒(méi)有被sp引用過(guò)。接下來(lái)判斷:

allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
|| impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
表示:如果對(duì)象的生命周期只受強(qiáng)引用控制,對(duì)象一定存在,要有強(qiáng)引用才可以管理對(duì)象的釋放,所以一定會(huì)允許生成強(qiáng)引用;如果對(duì)象的生命周期受弱引用控制,調(diào)用對(duì)象的onIncStrongAttempted試圖增加強(qiáng)引用,由于此時(shí)在弱引用中,弱引用一定不為0,對(duì)象也一定存在,調(diào)用onIncStrongAttempted的意圖是因?yàn)轭?lèi)的實(shí)現(xiàn)者可能不希望用強(qiáng)引用引用對(duì)象。在RefBase中onIncStrongAttempted默認(rèn)返回true:

bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id)
{
return (flags&FIRST_INC_STRONG) ? true : false;
}
如果curCount <= 0(只會(huì)等于0),表示對(duì)象強(qiáng)引用數(shù)經(jīng)歷了INITIAL_STRONG_VALUE -->大于0 --> 0,接下來(lái)就要判斷:

allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK
&& impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
如果對(duì)象的生命周期受強(qiáng)引用數(shù)控制,那么由于曾被sp引用過(guò),現(xiàn)在強(qiáng)引用數(shù)又為0,對(duì)象就已經(jīng)被delete了,所以就不能生成強(qiáng)引用,否則如果對(duì)象的生命周期受弱引用數(shù)控制,就通過(guò)onIncStrongAttempted看類(lèi)的實(shí)現(xiàn)者是否希望當(dāng)對(duì)象的強(qiáng)引用數(shù)變?yōu)?時(shí)可以再次被強(qiáng)引用引用。

if (!allow) {
decWeak(id);
return false;
}
如果allow為false表示不能從弱引用生成強(qiáng)引用,就要調(diào)用decWeak將弱引用減1(因?yàn)樵趐romote入口先將弱引用加了1),然后返回false表示生成強(qiáng)引用失敗。

if (curCount == INITIAL_STRONG_VALUE) {
android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);
impl->mBase->onFirstRef();
}
最后,如果curCount == INITIAL_STRONG_VALUE表示第一次被sp引用,調(diào)用對(duì)象的onFirstRef函數(shù)。

五、總結(jié)

RefBase內(nèi)部有一個(gè)指針指向?qū)嶋H對(duì)象,有一個(gè)weakref_impl類(lèi)型的指針保存對(duì)象的強(qiáng)/弱引用計(jì)數(shù)、對(duì)象生命周期控制。sp只有一個(gè)成員變量,用來(lái)保存實(shí)際對(duì)象,但這個(gè)實(shí)際對(duì)象內(nèi)部已包含了weakref_impl *對(duì)象用于保存實(shí)際對(duì)象的引用計(jì)數(shù)。sp 管理一個(gè)對(duì)象指針時(shí),對(duì)象的強(qiáng)、弱引用數(shù)同時(shí)加1,sp銷(xiāo)毀時(shí),對(duì)象的強(qiáng)、弱引用數(shù)同時(shí)減1。

wp中有兩個(gè)成員變量,一個(gè)保存實(shí)際對(duì)象,另一個(gè)是weakref_impl *對(duì)象。wp管理一個(gè)對(duì)象指針時(shí),對(duì)象的弱引用計(jì)數(shù)加1,wp銷(xiāo)毀時(shí),對(duì)象的弱引用計(jì)數(shù)減1。

weakref_impl中包含一個(gè)flag用于決定對(duì)象的生命周期是由強(qiáng)引用數(shù)控制還是由弱引用數(shù)控制:

當(dāng)flag為0時(shí),實(shí)際對(duì)象的生命周期由強(qiáng)引用數(shù)控制,weakref_impl *對(duì)象由弱引用數(shù)控制。

當(dāng)flag為OBJECT_LIFETIME_WEAK時(shí),實(shí)際對(duì)象的生命周期受弱引用數(shù)控制。

當(dāng)flag為OBJECT_LIFETIME_FOREVER時(shí),實(shí)際對(duì)象的生命周期由用戶(hù)控制。

可以用extendObjectLifetime改變flag的值。

    相關(guān)評(píng)論

    閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過(guò)難過(guò)
    • 5 囧
    • 3 圍觀圍觀
    • 2 無(wú)聊無(wú)聊

    熱門(mén)評(píng)論

    最新評(píng)論

    發(fā)表評(píng)論 查看所有評(píng)論(0)

    昵稱(chēng):
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過(guò)審核才能顯示)