Android中的sp和wp指標

2021-08-02 07:54:25 字數 3920 閱讀 8832

原址

經常會在android的framework**中發現sp和wp這樣的指標,平時看的時候都把他當成乙個普通的指標封裝過掉了,這幾天終於忍不住了,想深入了解一下。

相關的**:

frameworks/base/include/utils/refbase.h

frameworks/base/libs/utils/refbase.cpp

sp和wp都是乙個模板類,看一下sp類的定義:

[cpp]view plain

copy

template

<

typename

t>  

class

sp  

sp(t* other);  

sp(const

sp& other);  

~sp();  

......  

private

:      

// optimization for wp::promote().

sp(t* p, weakref_type* refs);  

t*              m_ptr;  

};  

可以看到他確實封轉了乙個原生指標t* m_ptr. 再看一下其中乙個建構函式和析構函式:

[c-sharp]view plain

copy

template

sp::sp(t* other)  

: m_ptr(other)  

template

sp::~sp()    

咋一看好奇怪,因為在建構函式中呼叫了incstrong(),在析構函式中呼叫的decstrong(),顯然是管理引用計數的函式,但是sp類的中並沒有定義這兩個函式,這兩個函式是在refbase類中定義的,由此可以得出結論:

要想使用sp或者wp, t必需要繼承refbase類才行。 

refbase的靜態關係如下: 

其中weakref_type是refbase的內嵌類,weakref_impl則是weakref_type的子類,refbase的大部分工作都是交由weakref_impl類來完成,通過refbase的成員變數weakref_impl* const mrefs。檢視其中乙個sp的建構函式:

[c-sharp]view plain

copy

template

sp::sp(t* other)  

: m_ptr(other)    

建立sp的動態關係如下:

sp--> refbase : incstrong()

-->weakref_impl : addstrongref()

-->android_atomic_inc(&refs->mstrong)

可見當乙個普通指標變成乙個sp指標後,將會由refbase類維護該指標的引用計數,當引用為零時則自動釋放該指標指向的記憶體:

[c-sharp]view plain

copy

void

refbase::decstrong(

const

void

* id) 

const

}  refs->removeweakref(id);  

refs->decweak(id);  

}  

wp其實是弱指標的意思,wp型別不能直接對型別t進行操作,要想對t進行某種操作,必需把wp公升級為sp指標,使用promote()來實現公升級:

wpweakp= new t();

spt = weakp.promote();

wp可能會在弱引用計數不為0的情況下被銷毀,執行如下**:

[c-sharp]view plain

copy

class

wptest : 

public

refbase   

virtual

~wptest()   

virtual

void

onfirstref()   

virtual

void

onlaststrongref(

const

void

* id)   

virtual

void

onlastweakref(

const

void

* id)   

};  

intmain()  

logd("weak ptr's lifetime is just about to finish .../n"

);  

}  logd("weak ptr is out of scope./n"

);  

return

0;  

}  

程式列印的結果是:

d/sp-wp-sample(  225): wptest constructor

d/sp-wp-sample(  225): promote to strong ptr...

d/sp-wp-sample(  225): first weak ptr ref callback

d/sp-wp-sample(  225): strong ptr's lifetime is just about to finish ...

d/sp-wp-sample(  225): last strong ptr ref callback

d/sp-wp-sample(  225): wptest destructor

d/sp-wp-sample(  225): weak ptr's lifetime is just about to finish ...

d/sp-wp-sample(  225): weak ptr is out of scope.

由此可見雖然wp的生命週期還沒有結束,但是因為公升級為sp後,sp的強引用計數為0,導致wptest 被銷毀,當強引用為0而弱引用不為0時,wptest 銷毀時,基類refbase的mrefs指向的weakref_impl類並沒有釋放,從而保證了弱引用可以繼續起作用,這點可以從refbase的析構函式中看出來:

[c-sharp]view plain

copy

refbase::~refbase()  

}  不過也可以改變這一行為,我們修改一下wptest的建構函式:

[c-sharp]view plain

copy

wptest()  

這時的列印結果是:

d/sp-wp-sample(  217): wptest constructor

d/sp-wp-sample(  217): promote to strong ptr...

d/sp-wp-sample(  217): first weak ptr ref callbac

d/sp-wp-sample(  217): strong ptr's lifetime is j

d/sp-wp-sample(  217): last strong ptr ref callba

d/sp-wp-sample(  217): weak ptr's lifetime is j

d/sp-wp-sample(  217): last weak ptr ref callback

d/sp-wp-sample(  217): wptest destructor

d/sp-wp-sample(  217): weak ptr is out of scope.

可以看出現在只有當強引用和弱引用的計數都為0時,wptest物件才會被銷毀。

Android中的sp和wp指標

經常會在android的framework 中發現sp和wp這樣的指標,平時看的時候都把他當成乙個普通的指標封裝過掉了,這幾天終於忍不住了,想深入了解一下。相關的 frameworks base include utils refbase.h frameworks base libs utils r...

Android中的sp和wp指標

經常會在android的framework 中發現sp和wp這樣的指標,平時看的時候都把他當成乙個普通的指標封裝過掉了 frameworks base include utils refbase.h frameworks base libs utils refbase.cpp sp和wp都是乙個模板...

Android中dip和sp的真正區別

估計很少有人知道android裡面dip和sp的真正區別,無論你在網上怎麼搜,搜出來的結果都是告訴你字型用sp,尺寸用dip 可是為什麼字型用sp呢?谷歌為什麼要這麼定呢?這兩個單位之間到底有什麼區別呢?其實這兩個單位在大小上沒有任何區別。唯一的區別就是在系統設定裡。你手機的系統設定是不是有這麼個可...