[英]Release in iPhone
每當我讀到有關如何避免內存泄漏的知識時,我總會遇到一個概念:“分配數必須等於釋放數”。
但是我遇到了一個概念,我們需要多個發行版。 就像我以前練習的一樣:
(NSString*) func1
{
NSString* result = [[NSString alloc] initWithFormat:@"Test String"]];
return result;
}
(void) func2
{
NSString* temp = [self func1];
[temp release];
}
但是我遇到了保留計數的概念,該概念表示在上述情況下,由於該字符串的保留計數最后為1,因此未為該字符串釋放內存。 所以正確的做法是
(NSString*) func1
{
NSString* result = [[NSString alloc] initWithFormat:@"Test String"]];
[result autorelease];
return result;
}
(void) func2
{
NSString* temp = [self func1];
[temp release];
}
因此,現在我有兩個釋放內存的版本,這與我在大多數博客上讀到的“上面的句子”“分配數量必須等於釋放數量”是矛盾的。
我對以上內容有些困惑。 Becoz,如果我在第一個函數中自動釋放該字符串並想長時間使用第二個函數中的字符串,並且如果釋放池在兩者之間被刷新怎么辦,另一方面,如果我不使用自動釋放,它將仍然阻塞內存。
那么正確的做法是什么。
在您調用alloc
,返回的任何內容的retainCount
均為1。對該對象調用release
會導致該對象被釋放(它的retainCount
會降至0)。 然后,在您的第一個示例中, func2
的第二行將取消分配您從func1
收到的NSString*
,並且您的內存管理工作已經完成。
在第二個示例中,您正在將func1
result
扔到當前的自動釋放池中,這將導致池耗盡時將其釋放。 一旦將對象放到池中,您就不想嘗試管理該對象的內存,這不再是您的責任。
如果要生成字符串並將其保留一段時間(例如,在多個自動釋放池的整個生命周期中),則建議使用第一種形式的內存管理。
正確的方法是這樣的:
(NSString*) func1 {
NSString* result = [[NSString alloc] initWithFormat:@"Test String"];
// retaincount == 1
return [result autorelease];
}
(void) func2 {
NSString* temp = [self func1];
// retaincount == 1
// temp is autoreleased, therefore no [release] is necessary.
}
自動釋放在運行循環結束時自動完成,這意味着在代碼執行某些操作時無法將其清空。 ->您擁有的代碼是安全的。 對於多線程應用程序,情況並非如此!
(NSString*) func1
{
NSString* result = [[NSString alloc] initWithFormat:@"Test String"]];
return result;
}
[結果keepCount]為1
(void) func2
{
NSString* temp = [self func1];
[temp release];
}
[temp keepCount]為0
無需自動發布。
從內存管理規則 :
這是基本規則:
如果使用名稱以“ alloc”或“ new”開頭或包含“ copy”(例如alloc,newObject或mutableCopy)的方法創建對象,或者向其發送保留消息,則您擁有該對象的所有權。 您有責任使用release或autorelease放棄您擁有的對象的所有權。 任何其他時間收到對象時,都不得釋放它。 以下規則源自基本規則,或應付極端情況:
作為基本規則的必然結果,如果您需要將接收到的對象作為屬性存儲在實例變量中,則必須保留或復制它。 (對於弱引用(在“對象的弱引用”中描述的情況並非如此,但通常很少見。)通常保證已接收對象在其所接收的方法內保持有效(例外包括多線程應用程序和某些分布式對象)情況,不過如果您修改從中收到對象的對象,也必須格外小心。 該方法還可以安全地將對象返回給它的調用者。 如果需要,可以將保留與釋放或自動釋放結合使用,以防止對象由於消息的正常副作用而失效(請參閱“共享對象的有效性”)。
自動釋放僅表示“稍后發送釋放消息”(有關稍后的某些定義,請參閱“自動釋放池”)。
通常,保留返回值會更安全,例如“ func 2”中的返回值:
(NSString*) func1 {
NSString* result = [[NSString alloc] initWithFormat:@"Test String"];
return [result autorelease];
}
(void) func2 {
NSString* temp = [[self func1] retain];
// Do something with temp
[temp release];
}
這是不必要的嗎? 我知道在此示例中,“ temp”只是局部變量。 但是它可能是一個實例變量,可能需要保留。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.