記憶體管理策略

2021-07-04 03:18:48 字數 2888 閱讀 6978

在引用計數的環境下管理記憶體使用的基本模型是,通過在nsobject協議定義的方法和提供標準命名的方法。nsobject類也定義了乙個方法「dealloc」,當乙個物件被釋放時此函式被呼叫。本文介紹了您需要知道的,如何正確的管理內存在乙個cocoa程式,並提供了一些正確的使用例項。

記憶體管理模型是基於物件所有權的。任何乙個物件可能會有乙個或者多個所有者。只要乙個物件有至少乙個所有者,那麼它需要繼續退出。當乙個物件沒有所有者時,系統會自動銷毀它。

為了確保你是否清除乙個物件,cocoa提供以下策略:

用「alloc」,「new」,「copy」,或「mutablecopy」方法建立物件。(例如,alloc,newobject,或mutablecopy)。

通過retain這個方法可以有效地保證原物件被引用,這個方法也安全地放回原物件的呼叫者。可以在以下兩個情況下使用retain方法:

(1)實現乙個訪問物件的方法或者init方法,為了得到想儲存物件所有權作為屬性時。

(2)為了防止一些其他操作造成物件被廢棄。(如:使用了乙個被廢棄的物件)

通過傳送release訊息或autorelease訊息放棄物件的所有權。在cocoa術語中,放棄物件被稱為「釋放」物件。

這是前面規則的推論。

為了說明該策略,考慮下面的**片段:

這個person物件是由alloc方法建立的,所以隨後當不需要時傳送release訊息進行釋放。這個人的名字變數沒有被任何乙個方法所取用,所以它不用傳送release訊息。注意,這個例子使用的是釋放而不是自動釋放。

當需要放送乙個延遲釋放訊息時,你可以使用autorelease。這通常是在返回乙個物件方法時使用。下面舉乙個例子,你可以實現獲取人的名字方法像這樣:

- (nsstring *)fullname

通過alloc方法獲取到了這個string。要遵守記憶體管理策略,那麼當不再引用物件時,必須放棄所有權。如果使用release,那麼此string將要在返回前被析構掉了(此時該函式將返回乙個無效的物件)。使用autorelease就意味著想要釋放所有權,但允許呼叫方法在該物件釋放前使用。

也可以用下面的方式實現:

- (nsstring *)fullname

根據基本的規則,由於沒有從stringwithformat方法得到返回string的所有權,所以可以放心地通過此方法返回string。

相比之下,下面的實現方式是錯誤的:

- (nsstring *)fullname

根據命令規定,沒有說明fullname方法的呼叫方擁有返回字串的所有權。因此呼叫方沒有理由釋放字串,這樣就造成記憶體洩漏。

在cocoa框架中有一些特殊的方法,他們返回物件的引用(他們的引數型別可能是classname**或者id*)。比較常見的方法就是,當發生了乙個錯誤,通過nserror儲存出錯資訊。如下所示:

initwithcontentsofurl:options:error: (nsdata) and initwithcontentsoffile:encoding:error: (nsstring).

在這些情況下,同樣的規則也適用於此。當呼叫這些方法,你沒有建立物件,那麼你沒有物件的所有權,所以也不需要釋放它。如下例子所示:

nsstring *filename = <#get a file name#>;

nserror *error;

nsstring *string = [[nsstring alloc] initwithcontentsoffile:filename

encoding:nsutf8stringencoding error:&error];

if (string == nil)

// ...

[string release];

nsobject類定義了dealloc方法。當物件沒有擁有者,或者記憶體被**時,該方法自動呼叫。這個方法的作用是釋放物件的記憶體,並處理它擁有的任何資源,包括任何物件例項變數的所有權。

下面這個例子描述怎麼實現person類的dealloc方法:

@inte***ce person : nsobject

@property (retain) nsstring *firstname;

@property (retain) nsstring *lastname;

@property (assign, readonly) nsstring *fullname;

@end

@implementation person

// ...

- (void)dealloc

[_firstname release];

[_lastname release];

[super dealloc];

}@end

注意:不要直接呼叫任何物件的dealloc方法。

在dealloc函式實現方法結束前,要呼叫父類的dealloc方法。

不應該把系統資源的管理放到物件生命週期中;不用用dealloc方法管理稀缺資源。

當應用程式中斷時,物件不可能傳送dealloc訊息。因為程序的內存在退出時自動清除,所以更高效的作業系統來清除資源,而不是呼叫所有的記憶體管理方法。

有類似的管理規則給核心庫物件。cocoa和核心庫的命名規則是不同的。特別是核心庫的建立規則不適用於返回objective-c物件的方法。

舉乙個例子,在下面的**段中,你不負責釋放myinstance例項所有權的。

myclass *myinstance = [myclass createinstance];

記憶體管理策略!(13)

對於32位程序而言,這個位址空間的大小為4gb。而64位程序則可以到達16eb的位址空間。每個程序都有自己專有的位址空間,當程序中的執行緒執行時,他們只能訪問屬於該程序的記憶體。每個程序的虛擬空間都被劃分成許多分割槽 0x00000000 0x0000ffff是空指標賦值分割槽 0x00010000...

Redis記憶體管理 鍵過期策略 記憶體淘汰策略

記憶體使用統計指標 可以參考文章 其中需要重點關注的指標 used memory redis使用的記憶體總量 used memory rss 系統分配的記憶體總量 mem fragmentation ratio 記憶體碎片率 used memory rss used memory 當 mem fra...

IOS 學習筆記14 記憶體管理(2)記憶體管理策略

文章中帶有lpstudy的字樣表明是我個人的理解,可能會有不對的地方,敬請指教。html view plain copy 記憶體管理策略 在引用計數機制下,你可以採用nsobject protocol的方法和和標準的方法命名約定進行記憶體管理。nsobject也定義了乙個dealloc方法,它在物件...