NSString 的內存管理

前段時間看了同事的分享,于是把它記錄下來

先看下這幾個測試代碼,關于 NSString:

NSString *a = @"abc";
NSString *b = [[NSString alloc] init];
NSString *c = [[NSString alloc] initWithString:@"abc"];
NSString *d = [[NSString alloc] initWithFormat:@"abc"];
NSString *e = [NSString stringWithFormat:@"abc"];
NSString *f = [NSString stringWithFormat:@"123456789"];
NSString *g = [NSString stringWithFormat:@"1234567890"];

執(zhí)行后打印輸出結果:

變量名=a,類型=__NSCFConstantString
變量名=b,類型=__NSCFConstantString
變量名=c,類型=__NSCFConstantString
變量名=d,類型=NSTaggedPointerString
變量名=e,類型=NSTaggedPointerString
變量名=f,類型=NSTaggedPointerString
變量名=g,類型=__NSCFString

可以看出 NSString 是有幾種類型的:

  • __NSCFConstantString
    文字常量區(qū)存放常量字符串,程序結束后由系統(tǒng)釋放,也就是說指向常量表的指針不受引用計數(shù)管理。所以對于NSCFConstantString類型的變量,OC 的內存管理策略對其無效
  • NSTaggedPointerString
    對于64位程序,為了節(jié)省內存和提高運行速度,蘋果引入了 Tagged Point 技術。NSTaggedPointerString是對NSCFString優(yōu)化后的存在,在運行時創(chuàng)建時對字符串的內容和長度做出判斷,若字符串內容是由ASCII字符構成且長度較?。ù蟾攀畟€字符以內),這時候創(chuàng)建的字符串就是NSTaggedPointerString類型,字符串直接存儲在指針里,引用計數(shù)同樣為-1,不適用對象的內存管理策略
  • Tagged Pointer
    它的指針的值不再是地址了,而是真正的值。所以,實際上它不再是一個對象了,它只是一個披著對象皮的普通變量而已。所以,它的內存并不存儲在堆中,OC 對象的內存管理方式對其無效。
  • __NSCFString
    表示這是一個對象類型的字符串,在運行時創(chuàng)建,存儲在堆區(qū),服從OC 的對象內存管理策略。

我們可以看下面這張圖:


NSString 內存管理方式

關于NSString是不是還有很多驚喜呢?歡迎補充

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

相關閱讀更多精彩內容

  • 目錄1、存放位置2、構造方式3、特性分析4、內存分配5、總結6、思考題 我們在創(chuàng)建NSString對象時,其實對象...
    毅想天開的小毅閱讀 2,285評論 3 4
  • 本文主要包括NSString的內存管理問題,按照string的初始化方法來分析。還包括使用__weak后的影響 在...
    Sunxb閱讀 2,287評論 3 10
  • NSString的內存優(yōu)化 OC中的NSString不論是在編譯時還是在運行時都做了很多的優(yōu)化,并不同于普通的對象...
    二斤寂寞閱讀 385評論 0 0
  • iOS中,NSString對象相對其他OC對象的內存管理是復雜的。按照產(chǎn)生對象的isa,大致可以分為三種情況,如下...
    平原河流閱讀 993評論 0 2
  • 在學習自動釋放池與RunLoop的關系的時候發(fā)現(xiàn)申明NSString類型的變量未隨RunLoop的進入休眠而釋放,...
    1劍天下閱讀 538評論 0 1

友情鏈接更多精彩內容