黑馬程序員----Objective-C學習筆記之NSString類的內存管理問題

------Java培訓、Android培訓、iOS培訓、.Net培訓--------

【前情提要】

內存分配地址:棧區地址最高,堆區次之,常量區再次之

1、NSString等Foundation框架中類的內存管理

1)如果你需要的字符串在常量池中已經存在,則不會分配內存空間

【使用字符串的時候】@”“,stringWithString, alloc initWithString都是在常量區

【常量區的對象引用計數是無符號的最大值,如果用%ld輸出是-1,用retain和release是沒有用的】

【使用initWithFormat時字符串在堆區,前面有alloc時需要release,如果沒有系統會自動消滅,不用理會】

 

例如:

 

 @autoreleasepool {
        int a = 1;//棧區
        /*如果你需要的字符串在常量池中已經存在,則不會分配內存空間
        【使用字符串的時候】@”“,stringWithString, alloc initWithString都是在常量區
        */
        NSString *str1 = @"abc";//常量區
        NSString *str2 = [NSString stringWithString:@"abc"];//常量區
        NSString *str3 = [[NSString alloc] initWithString:@"abc"];//常量區
        /*【使用initWithFormat時字符串在堆區,前面有alloc時需要release,如果沒有系統會自動消滅,不用理會】
        */
        NSString *str4 = [NSString stringWithFormat:@"abc"];//堆區
        NSString *str5 = [[NSString alloc] initWithFormat:@"abc"];//堆區
      
        NSLog(@"a = %d,address = %p, retainCount = %lu",a,&a, str1.retainCount);
        NSLog(@"str1 = %@,address = %p, retainCount = %lu",str1,str1, str1.retainCount);
        NSLog(@"str2 = %@,address = %p, retainCount = %lu",str2,str2, str2.retainCount);
        NSLog(@"str3 = %@,address = %p, retainCount = %lu",str3,str3, str3.retainCount);
        NSLog(@"str4 = %@,address = %p, retainCount = %lu",str4,str4, str4.retainCount);
        NSLog(@"str5 = %@,address = %p, retainCount = %lu",str5,str5, str5.retainCount);
   }

打印結果:

2015-10-06 16:12:59.962 MRCDemo[2146:303] a = 1,address = 0x7fff5fbff93c, retainCount = 18446744073709551615

2015-10-06 16:12:59.964 MRCDemo[2146:303] str1 = abc,address = 0x1000023a8, retainCount = 18446744073709551615

2015-10-06 16:12:59.965 MRCDemo[2146:303] str2 = abc,address = 0x1000023a8, retainCount = 18446744073709551615

2015-10-06 16:12:59.965 MRCDemo[2146:303] str3 = abc,address = 0x1000023a8, retainCount = 18446744073709551615

2015-10-06 16:12:59.966 MRCDemo[2146:303] str4 = abc,address = 0x100109c80, retainCount = 1

2015-10-06 16:12:59.966 MRCDemo[2146:303] str5 = abc,address = 0x10010a660, retainCount = 1

 

 

【疑問1

NSString *str3 = [[NSString alloc] initWithString:@"abc"];爲什麼這樣也是alloc,但是卻是在常量區。因爲這種用法被Xcode特殊處理過。同樣地NSString *str2 = [NSString stringWithString:@"abc"];這種用法也是在常量區的。

【疑問2

 NSString *str4 = [NSString stringWithFormat:@"abc"];這種用法創建的字符串對象也是在堆區,但是一旦使用release就會掛掉。因爲,這種是由系統自動清理的,不需要手動release。而NSString *str5 = [[NSString alloc] initWithFormat:@"abc"];這種因爲手動調用了alloc方法,因此需要手動release

 

【危險用法】:使用retainCount作爲循環條件的判斷

        while ([str2 retainCount] > 0) {
           [str5 release];
       }


這種做法有可能導致死循環,不要使用retainCount作爲循環判斷條件


發佈了65 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章