android中的 sp,wp學習筆記
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()
這個又如何解呢。
求明白的給指正一下