iOS基礎知識之Tagged Pointer

舉例

描述tagged pointer技術前鲫忍,先做一道題:以下兩個case冀墨,會crash嗎?
case1

@property (noatomic, strong) NSString* val1;

dispatch_queue_t queue = dispatch_get_global_queue(0, 0); 
for (int i = 0; i < 1000; i++) { 
  dispatch_async(queue, ^{ 
    self.val1 = [NSString stringWithFormat:@"abcdefghijk"]; 
  }); 
}

case2

@property (noatomic, strong) NSString* val2;

dispatch_queue_t queue = dispatch_get_global_queue(0, 0); 
for (int i = 0; i < 1000; i++) { 
  dispatch_async(queue, ^{ 
    self.val2 = [NSString stringWithFormat:@"abc"]; 
  }); 
}

實際運行會發(fā)現(xiàn)献丑,case1崩潰了末捣,case2不會。case1會崩潰阳距,報錯BAD_ACCESS塔粒,這個原因不解釋了,不清楚的可以看我的文章:http://www.reibang.com/p/d0e5ec2d0d85
那為啥case2沒有崩潰了筐摘,這個就和tagged pointer的優(yōu)化有關了卒茬。經(jīng)過通過打印發(fā)現(xiàn)val1的class是 __NSCFString,str2的class是 NSTaggedPointerString咖熟,是兩個不同的String類型圃酵。(明明寫的NSString,為啥會不一樣馍管,這個涉及到 類簇的概念郭赐,后續(xù)文章會介紹)。

簡介

從64位開始确沸,iOS引入了Tagged Pointer技術捌锭,用于優(yōu)化NSNumber俘陷、NSDate、NSString等小對象的存儲观谦。

  • 在沒有使用Tagged Pointer之前拉盾, NSNumber等對象需要動態(tài)分配內(nèi)存、維護引用計數(shù)等豁状。
  • NSNumber指針存儲的是堆中NSNumber對象的地址值使用Tagged Pointer之后捉偏,NSNumber指針里面存儲的數(shù)據(jù)變成了:Tag + Data,也就是將數(shù)據(jù)直接存儲在了指針中泻红。
  • 當指針不夠存儲數(shù)據(jù)時夭禽,才會使用動態(tài)分配內(nèi)存的方式來存儲數(shù)據(jù)。
  • objc_msgSend能識別Tagged Pointer谊路,比如NSNumber的intValue方法讹躯,直接從指針提取數(shù)據(jù),節(jié)省了以前的調(diào)用開銷

可以理解為把指針指向的內(nèi)容直接放在了指針變量的內(nèi)存地址中缠劝,因為在 64 位環(huán)境下指針變量的大小達到了 8 字節(jié)足以容納一些長度較小的內(nèi)容蜀撑。于是使用了標簽指針這種方式來優(yōu)化數(shù)據(jù)的存儲方式。

  • 從其的引用計數(shù)可以看出剩彬,這也是一個釋放不掉的單例常量對象。當我們使用不同的字符串對象進行創(chuàng)建時當內(nèi)容相同矿卑,其對象的地址也相同喉恋。在運行時根據(jù)實際情況創(chuàng)建。
  • 對于 NSString 對象來講母廷,當非字面值常量的數(shù)字轻黑,英文字母字符串的長度小于等于 9 的時候會自動成為 NSTaggedPointerString 類型。

如何判斷是否是Tagged Pointer

#if __arm64__
#   define OBJC_SPLIT_TAGGED_POINTERS 1
#else
#   define OBJC_SPLIT_TAGGED_POINTERS 0
#endif

#if (TARGET_OS_OSX || TARGET_OS_MACCATALYST) && __x86_64__
    // 64-bit Mac - tag bit is LSB
#   define OBJC_MSB_TAGGED_POINTERS 0
#else
    // Everything else - tag bit is MSB
#   define OBJC_MSB_TAGGED_POINTERS 1
#endif

#if OBJC_SPLIT_TAGGED_POINTERS
#   define _OBJC_TAG_MASK (1UL<<63)
#elif OBJC_MSB_TAGGED_POINTERS
#   define _OBJC_TAG_MASK (1UL<<63)
#else
#   define _OBJC_TAG_MASK 1UL
#endif

static inline bool 
_objc_isTaggedPointer(const void * _Nullable ptr)
{
    return ((uintptr_t)ptr & _OBJC_TAG_MASK) == _OBJC_TAG_MASK;
}

答疑

  • 如何判斷一個指針是否為Tagged Pointer琴昆?
    • iOS平臺氓鄙,最高有效位是1(第64bit)
    • Mac平臺,最低有效位是1
  • Tagged Pointer的引用計數(shù)是多少业舍?
    • 通過打印retainCount的值:2^64 - 1抖拦,可以理解成不會dealloc
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市舷暮,隨后出現(xiàn)的幾起案子态罪,更是在濱河造成了極大的恐慌,老刑警劉巖下面,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件复颈,死亡現(xiàn)場離奇詭異沥割,居然都是意外死亡耗啦,警方通過查閱死者的電腦和手機凿菩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來帜讲,“玉大人衅谷,你說我怎么就攤上這事∈姘铮” “怎么了会喝?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長玩郊。 經(jīng)常有香客問我肢执,道長,這世上最難降的妖魔是什么译红? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任预茄,我火速辦了婚禮,結(jié)果婚禮上侦厚,老公的妹妹穿的比我還像新娘耻陕。我一直安慰自己,他們只是感情好刨沦,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布诗宣。 她就那樣靜靜地躺著,像睡著了一般想诅。 火紅的嫁衣襯著肌膚如雪召庞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天来破,我揣著相機與錄音篮灼,去河邊找鬼。 笑死徘禁,一個胖子當著我的面吹牛诅诱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播送朱,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼娘荡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了骤菠?” 一聲冷哼從身側(cè)響起它改,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎商乎,沒想到半個月后央拖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年鲜戒,在試婚紗的時候發(fā)現(xiàn)自己被綠了专控。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡遏餐,死狀恐怖伦腐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情失都,我是刑警寧澤柏蘑,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站粹庞,受9級特大地震影響咳焚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜庞溜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一革半、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧流码,春花似錦又官、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至驾荣,卻和暖如春觉阅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背秘车。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留劫哼,地道東北人叮趴。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像权烧,于是被迫代替她去往敵國和親眯亦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容