您好,登錄后才能下訂單哦!
今天遇到了幾個和字符串相關的內存問題,和大家分享一下
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 alloc] init]; // 返回的對象類型:__NSCFConstantString
NSString *string2 = [[NSString alloc] initWithFormat:@"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;其實和上面是相同的
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。