1. 程式人生 > >android中的 sp,wp學習筆記

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()
  這個又如何解呢。
求明白的給指正一下