Tagged Pointer小知識

運(yùn)行下面兩段代碼,會發(fā)生什么事?

這兩段代碼看似一致,其實(shí)結(jié)果差別很大,代碼1會崩潰(奔潰信息如下),代碼2卻不會;


從報錯信息可以看出原因是壞內(nèi)存訪問,現(xiàn)在使用的是ARC,但是ARC的底層實(shí)現(xiàn)是MRC,如下:

//self.name賦值MRC實(shí)現(xiàn)
- (void)setName:(NSString *)name
{
    if (_name != name) {
        [_name release];
        _name = [name retain];
    }
}

由于線程不安全,多條線程同時執(zhí)行了[_name release];這行代碼,所以下一個線程進(jìn)來的時候,發(fā)現(xiàn)self.name已經(jīng)被釋放了,那么就會出現(xiàn)壞內(nèi)存訪問的情況;

那么為什么代碼2沒有崩潰呢?
這是因?yàn)閺?4bit開始,iOS引入了Tagged Pointer技術(shù),用于優(yōu)化NSNumber、NSDate、NSString等小對象的存儲,這些較小的對象,直接存儲在棧區(qū),所以線程不安全并沒有影響到棧區(qū)。

arm64架構(gòu)后指針有64位,于是把空余的位利用起來,存儲對象值,這個就是Tagged Pointer

打印查看兩字符對象的地址:



可以看出str2的地址明顯高于str1,因?yàn)闂^(qū)的地址值,要在堆區(qū)之上,可以簡易推測str2的值直接存在指針上。

詳細(xì)的Tagged Pointer介紹有好多博客

深入理解Tagged Pointer

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容