經常會在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 util...
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呢?谷歌為什麼要這麼定呢?這兩個單位之間到底有什麼區別呢?其實這兩個單位在大小上沒有任何區別。唯一的區別就是在系統設定裡。你手機的系統設定是不是有這麼個可...