设为首页 加入收藏

TOP

Android智能指针sp wp详解(四)
2014-11-24 08:22:46 来源: 作者: 【 】 浏览:8
Tags:Android 智能 指针 详解
BBinder对象
}
}// 如果此时还有其他指向该目标对象的sp指针存在的话,就不会删除目标对象

refs->removeWeakRef(id);
refs->decWeak(id);
/* 删除新建目标对象sp指针时在mWeakRefs链表上增加的两个ref_entry结构体 */
}
/*********************************注释3*********************************/
void removeStrongRef(const void* id)
{
if (!mRetain) // mRetain 初始化成 flase
removeRef(&mStrongRefs, id);
/* 删除mStrongRefs链表中对应id的ref_entry一项 */
/* 也就是取消了该sp对象和目标对象的联系 */
else
addRef(&mStrongRefs, id, -mStrong);
}

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;
}
}
}
/*********************************注释3*********************************/

delete BB_wp_ptr;
这是删除目标对象的一个wp指针,会调用wp的析构函数:
template
wp::~wp()
{
if (m_ptr) m_refs->decWeak(this);
}
调用weakref_type类的decWeak()函数,如下:
void RefBase::weakref_type::decWeak(const void* id)
{
weakref_impl* const impl = static_cast(this);
impl->removeWeakRef(id);// 移除weakref_impl对象mWeakRefs链表中对应id的ref_entry结构体
const int32_t c = android_atomic_dec(&impl->mWeak);// 引用计数减1
LOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
if (c != 1) return; // c == 1, 说明这是系统中存在的指向目标对象的最后一个wp指针

if ((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
if (impl->mStrong == INITIAL_STRONG_VALUE)
delete impl->mBase;
// delete impl; 是不是应该加上这么一句,防止用户新建了wp后,不用,马上又删除的情况呢?
/* 当目标对象的最后一个wp被析构时,如果目标对象还没有建立任何一个sp,那么目标对象被删除 */
else {
delete impl;
/* 当目标对象的最后一个wp被析构时,但此时和目标对象相关的sp全部被析构,那么impl->mStrong = 0
在最后一个sp被析构的时候,目标对象也被释放,所以此时只需要释放weakref_impl对象即可
*/
}
} else {
impl->mBase->onLastWeakRef(id);
if ((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) {
delete impl->mBase;
}
}
}


四、wp升级为sp的过程
wp的定义包含了:sp promote() const;
template
sp wp::promote() const
{
return sp(m_ptr, m_refs);
}
wp,sp互为友元类,这里promote就是以友元身份调用了sp类的构造函数: sp(T* p, weakref_type* refs);
template
sp::sp(T* p, weakref_type* refs)
: m_ptr((p && refs->attemptIncStrong(this)) p : 0)
{
}
这里如果升级成功,那么将会产生一个sp对象指向目标对象,原来的wp仍然存在。
如果升级不成功,返回NULL
看看关键函数refs->attemptIncStrong(this)


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

weakref_impl* const impl = static_cast(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;
}// 系统中还有其他sp指向目标对象的情况

if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
bool allow;
if (curCount == INITIAL_STRONG_

首页 上一页 1 2 3 4 下一页 尾页 4/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Android编译系统 - findleaves.sh 下一篇Redboot mini2440 qemu 增加LCD功..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·MySQL 基础入门视频 (2025-12-26 23:20:22)
·小白入门:MySQL超详 (2025-12-26 23:20:19)
·关于 MySQL 数据库学 (2025-12-26 23:20:16)
·SOLVED: Ubuntu 24.0 (2025-12-26 22:51:53)
·Linux 常用命令最全 (2025-12-26 22:51:50)