OC中的類簇的使用和初始化方法中屬性的使用

今天遇到了幾個和字符串相關的內存問題,和大家分享一下

NSString *name = [[NSString alloc]initWithString:@"張三"];
NSLog(@"%d",[name retainCount]);

這兩行代碼的打印結果是-1,

NSString * aString = [[NSString alloc] initWithFormat:@"123"]; 
NSLog(@"%d",aString.retainCount);

這兩行代碼的打印結果也是-1

NSString * aString = [[NSString alloc] initWithFormat:@"1233sfsf4545f"]; 
NSLog(@"%d",aString.retainCount);

當就字符串變爲上面所述時,打印結果變爲了1

這就奇怪了,爲什麼相同的語法打印的結果會是不同呢?反過來分析,打印結果是-1說明引用指向的是常量區的字符串,打印結果是1指向的是堆區的字符串。由於OC是不開源的,內部的實現我們不得而知,但是從中我們至少可以猜測,OC中對不同大小的字符串是由不同的方法的。

  initWithString產生的是將指針指向了常量區的字符串,是無法被release的,如果使用dealloc進行摧毀會報錯。其一:不能手動調用dealloc方法 再者蘋果官方文檔中說的很清楚,創建的對象和retain的對象爲自己所保有,這些對象全部都是在堆區的。靜態區的內存實在編譯時就分配好了的,它的內存地址非常靠前,而且在程序運行的整個階段都存在,所以我們不能釋放。

關於類簇(class cluster)大家舉得最多的例子就是NSNumber類,其實NSNumber類是一個抽象的超類,內部有很多的具體的子類,如NSInt NSDouble等,它們對應不同的初始化方法,也就是說NSNumber的不同初始化方法返回的類型是不同的。不僅NSNumber,NSString也是如此,

 // 類簇的使用
  
id someClass = [NSString alloc]; // 返回的對象類型:NSPlaceholderString
  
  
NSString *string1 = [[NSString allocinit]; // 返回的對象類型:__NSCFConstantString
  
NSString *string2 = [[NSString allocinitWithFormat:@"string2"]; // 返回的對象類型:__NSCFString
  
NSLog(@"%@", string1);
  
NSLog(@"%@", string2);

類簇可以簡化一個面向對象的公開架構,而又不減少功能的豐富性


我們在項目中肯定會遇到類的初始化方法傳參的情況,如果實在MRC模式下,如何保證內存不leak,蘋果的官方文檔做了如下推薦

- (id)initWithName:(NSString*)name{

    self = [super init];

       if(self){

            _name = [name copy];// 當然name屬性的語義控制要使用copy

        }

        return self;

}

使用self.name = name;其實和上面是相同的


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章