国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > iOS > 正文

iOS源碼閱讀必備知識(shí)之Tagged Pointer

2020-07-26 02:25:42
字體:
供稿:網(wǎng)友

Tagged Pointer 介紹

蘋果對于Tagged Pointer特點(diǎn)的介紹:

  • Tagged Pointer專門用來存儲(chǔ)小的對象,例如NSNumber和NSDate
  • Tagged Pointer指針的值不再是地址了,而是真正的值。所以,實(shí)際上它不再是一個(gè)對象了,它只是一個(gè)披著對象皮的普通變量而已。所以,它的內(nèi)存并不存儲(chǔ)在堆中,也不需要malloc和free。
  • 在內(nèi)存讀取上有著3倍的效率,創(chuàng)建時(shí)比以前快106倍。

為什么要引入Tagged Pointer

iPhone5s 采用64位處理器。對于64位程序,我們的數(shù)據(jù)類型的長度是跟CPU的長度有關(guān)的。

這樣就導(dǎo)致了 一些對象占用的內(nèi)存會(huì)翻倍。

同時(shí) 維護(hù)程序中的對象需要 分配內(nèi)存,維護(hù)引用計(jì)數(shù),管理生命周期,使用對象給程序的運(yùn)行增加了負(fù)擔(dān)。

Tagged Pointer

為了改進(jìn)上面提到的內(nèi)存占用和效率問題,蘋果提出了Tagged Pointer對象。由于NSNumber、NSDate一類的變量本身的值需要占用的內(nèi)存大小常常不需要8個(gè)字節(jié),拿整數(shù)來說,4個(gè)字節(jié)所能表示的有符號(hào)整數(shù)就可以達(dá)到20多億(注:2^31=2147483648,另外1位作為符號(hào)位),對于絕大多數(shù)情況都是可以處理的。

我們可以將一個(gè)對象的指針拆成兩部分,一部分直接保存數(shù)據(jù),另一部分作為特殊標(biāo)記,表示這是一個(gè)特別的指針,不指向任何一個(gè)地址。所以,引入了Tagged Pointer對象之后,64位CPU下NSNumber的內(nèi)存圖變成了以下這樣:

Tagged Pointer

測試

#import int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... NSNumber *number1 = @1; NSNumber *number2 = @2; NSNumber *number3 = @3; NSNumber *numberFFFF = @(0xFFFF); NSNumber *numberLager = @(MAXFLOAT); NSLog(@"number1 pointer is %p", number1); NSLog(@"number2 pointer is %p", number2); NSLog(@"number3 pointer is %p", number3); NSLog(@"numberLager pointer is %p", numberLager); /* 2017-03-10 12:07:50.731726 TaggedPoint[1690:50438] number1 pointer is 0x127 2017-03-10 12:07:50.731992 TaggedPoint[1690:50438] number2 pointer is 0x227 2017-03-10 12:07:50.732011 TaggedPoint[1690:50438] number3 pointer is 0x327 2017-03-10 12:07:50.732043 TaggedPoint[1690:50438] numberLager pointer is 0x1002006a0 */ } return 0;}

以 0x127 為例 去掉 tag27(假設(shè)27為標(biāo)記) 0x1 就是number 的值。

0x227

0x327

都有這種規(guī)律

numberLager 存儲(chǔ)的值為MAXFloat 顯然超過了tagged pointer 可以存儲(chǔ)的范圍。

所以打印的地址是單純的指針地址,指向存儲(chǔ)numberLager的內(nèi)存地址。

對于isa指針的影響

因?yàn)閠agged pointer 不是一個(gè)真正的對象,如果使用isa指針在編譯時(shí)會(huì)報(bào)錯(cuò)。

如圖:

提示我們改為object_getClass()

object_getClass()中做了相應(yīng)的處理

由于object_getClass()沒有對應(yīng)的實(shí)現(xiàn),只能從其他地方窺探一二

objc-weak.mm

weak_read_no_lock(weak_table_t *weak_table, id *referrer_id) { objc_object **referrer = (objc_object **)referrer_id; objc_object *referent = *referrer; if (referent->isTaggedPointer()) return (id)referent; //...}
inline bool objc_object::isTaggedPointer() {#if SUPPORT_TAGGED_POINTERS return ((uintptr_t)this & TAG_MASK);#else return false;#endif}

這里取對象的值做了一些判斷

如果是tagged pointer , 對象的值就是指針

如果非tagged pointer , 對象的值是指針指向的內(nèi)存區(qū)域中的值

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對武林網(wǎng)的支持。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 永清县| 定兴县| 蕲春县| 连南| 即墨市| 山阳县| 东丰县| 桃园市| 石楼县| 民权县| 洛川县| 丹棱县| 芦溪县| 文成县| 钟祥市| 遂平县| 仁化县| 内乡县| 阳高县| 兰坪| 西安市| 禹城市| 广宁县| 武威市| 化州市| 扎赉特旗| 东乌| 咸宁市| 齐齐哈尔市| 安溪县| 清流县| 肥东县| 徐州市| 汝阳县| 曲沃县| 商城县| 金川县| 尼玛县| 普兰县| 隆安县| 武威市|