iOS tagged pointer

iOS tagged pointer

從 64bit 開始,蘋果引入了 tagged pointer 計數,用于優化 NSNumber , NSDate , NSString 等小對象的存儲,沒有這個數據之前,NSNumber 等對象需要動態分配內存,維護引用計數,NSNumber 指針存儲的是堆中NSNumber對象的地址值,而引入了這個計數之后,NSNumber 指針里面存儲的數據是 : tag + data ,也就是直接將數據存儲在指針中。這樣做特別節省空間。如果這個數據特別大,指針存儲不下這個數,那么會回復之前的方式,存儲在堆區,然后指針存放堆區的地址。

dispatch_queue_t queue = dispatch_get_global_queue(0, 0 );
    for (int i = 0 ; i < 10000; i ++) {
        dispatch_async(queue, ^{
            self.name = [NSString stringWithFormat:@"%@",@"123sdfasfdas"];
        });
    }

上面會發生什么呢?答案是可能崩潰,因為我們是多線程同時方位name的set方法,那么的set方法好比


-(void)setName:(NSString *)name{
    if (_name != name) {
        [_name release];
        _name = [name copy];
    }
}

好比這樣,多個線程有可能同時去 release,所以會崩潰

解決方案,可以加鎖,在name設置前后去加鎖。

如果改成這樣呢?


dispatch_queue_t queue = dispatch_get_global_queue(0, 0 );
    for (int i = 0 ; i < 10000; i ++) {
        dispatch_async(queue, ^{
            self.name = [NSString stringWithFormat:@"%@",@"123"];
        });
    }
    

就是把一個長字符串變成一個短的字符創,這時候發現,沒有崩潰。因為后一個指針為 tagged pointer 類型的,就不存在release的操作,值直接就存儲再來指針的里面,直接取值就可以了,所以就不會崩潰,他就不是一個OC對象。


 NSString *str = [NSString stringWithFormat:@"123"];
    NSString *str1 = [NSString stringWithFormat:@"aefasfasdfasfdasf"];
    NSLog(@"%@  %@",[str class],[str1 class]);


我們來打印下兩個類


 NSTaggedPointerString  __NSCFString

可以看到 第一個類為 tagged pointer 類,也證明了我們的猜想。

其實源碼里面是有判斷的,當為mac 的時候 &1,當為ios的時候&(1<<63),所以 ios 最高有效位為1就為 tagged pointer 類型,mac 最低有效位為1就為tagged pointer

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 這篇文章是參考很多資料才寫出來的,有部分內容這幾位寫的都很詳細到位,所以就直接拷貝了,這里向這幾位作者學習:深入理...
    晨寂閱讀 7,192評論 3 25
  • Tagged Pointer 介紹 蘋果對于Tagged Pointer特點的介紹: Tagged Pointer...
    Q14閱讀 473評論 0 0
  • Tagged Pointer是什么 我們知道,通常情況下,定義一個變量所占用的內存是與CPU的位數有關,比如NSI...
    米嘉勒閱讀 985評論 1 3
  • 一. 內存區域 驗證上圖,代碼如下: 運行后,整理打?。?可以發現: 上面的內存地址從小到大。 字符串常量一樣的時...
    Imkata閱讀 595評論 1 2
  • 大魚的心路 忽如一陣大雨 大魚 救贖 大愚 如一臺壓路機 碾平一路坑洼 心路坦蕩 一生無涯 (在小說《大魚》?的閱...
    安徽江美琳閱讀 104評論 0 1