溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

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

發(fā)布時間:2020-08-05 14:06:28 來源:網(wǎng)絡(luò) 閱讀:589 作者:機緣巧合 欄目:開發(fā)技術(shù)

今天遇到了幾個和字符串相關(guān)的內(nèi)存問題,和大家分享一下

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

這兩行代碼的打印結(jié)果是-1,

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

這兩行代碼的打印結(jié)果也是-1

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

當(dāng)就字符串變?yōu)樯厦嫠鰰r,打印結(jié)果變?yōu)榱?

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

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

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

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

類簇可以簡化一個面向?qū)ο蟮墓_架構(gòu),而又不減少功能的豐富性


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

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

    self = [super init];

       if(self){

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

        }

        return self;

}

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


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI