1.如何才能支持sp,wp
只支持sp的情况,只要实现下面2个函数就行
class simpleRefbase{
void incStrong(const void* id);
void decStrong(const void* id);
};这就是我们常规实现的简单引用计数方法。
android已经帮我们实现了一个LightRefBase<T>
支持sp并且支持wp
需要继承 android实现的RefBase
class RefBase{
void incStrong(const void* id);
void decStrong(const void* id);
weakref_type* createWeak(const void* id);
影子对象,监控sp,wp的使用情况,其实这个对象主要就是围绕下面的mRefs进行的
weakref_impl* mRefs;
}
2. RefBase每次new RefBase的时候,都会伴随着new一个影子对象new ref,
RefBase(){
mRefs=new weakref_impl();
}
影子对象就是监控着这个RefBase的使用情况的,主要包括sp了多少次 strong,wp了多少次 weak,监控的那个对象base。
当最后一个sp被干掉的时候(strong==0),就delete base, 当最后一个wp被干掉的(weak==0),就delete ref
~RefBase{
if(weak==0)
delete mRefs;
}
3.那什么时候会执行析构函数呢?
strong==0 就是最后一个sp被干掉的时候,
delete base;--> ~RefBase(){}
4. sp,wp
强指针
classe sp<T>{
T* base;
}
只要存在这样的对象,则内部保存的指针就是有效的base!=null,sp会同时增加强弱引用计数 strong++,weak++
弱指针
class wp<T>{
T* base;
void* ref; ref其实就指向base->mRefs
}
只要存在这样的对象,则内部保存的指针使用情况的对象(ref)就有效的,而base不一定有效。
弱引用计数一定大于等于强引用计数
5. 那这样需要怎样使用wp中的base呢?
因为base的生命周期只跟sp(strong)有关,所有现在无法确定wp中的base是否有效,这就需要一系列的判断的。
ref->attempIncStrong判断是否能增加强引用计数,如果能则base有效,也就是可以有wp生成一个sp。
sp<T> =wp<T>->promoto();
attempIncStrong分析
(1).是否第一次引用base , strong原始值==INITIAL_STRONG_VALUE,返回true
(2).是否有其他sp引用了base , strong原始值>0,返回true
(3).是否其他sp引用了base,但是有其他多线程的地方释放了sp ,造成strong原始值<=0,返回false
6. attempIncStrong
int cur=ref->mStrong;
//如果对象被强引用多(cur!=INITIAL_STRONG_VALUE),并且还有有效的sp(强引用计数>0),则进入while,对Strong+1
//while主要目的是防止多线程操作m_Strong,造成数据的不一致
while(cur>0&&cur!=INITIAL_STRONG_VALUE){
if(android_atomic_cmpcchg(cur,cur+1,&ref->m_Strong)==0)
break;
cur=ref->m_Strong;
}
//如果没有强引用过
if(cur==INITIAL_STRONG_VALUE){
}
//如果多线程释放过sp
if(cur<=0){
}
7.还存在疑问的地方
问题1.
线程1进行释放 sp1<xx> ~sp1<xx>
void decStrong()
{
1. int c=android_atomic_dec(&mStrong);
2. if(c==1){
3. onLastStrongRef();
4. delete this;
5. }
6. decWeak();
}
线程2进行构造 sp2<xx>=sp1<xx>
void incStrong(){
1. incWeak();
2. int c=android_atomic_dec(&mStrong);
}
当线程1 执行decStrong line1返回c=1,同时线程2执行incStrong line2,返回c=0.
这是sp2<T>已经指向一个无效的对象了。这个如何解呢?如果真存在这个问题那RefBase中很多地方存在incWeak,attempincStrong...
问题2.
attempIncStrong中好像进行了2次的增加强引用
android_atomic_cmpxchg()
android_atomic_inc()
这个又如何解呢。
求明白的给指正一下