2011-09-02 59 views
2

我有返回類型爲(NSArray/NSData/NSString/NSDictionary等)的函數。我可以返回並使用,但是我的問題出現了@釋放對象。請指導我哪一個是爲object.if東西回來是錯的請無視管理內存,並給最好的IOS內存管理@函數調用返回分配的對象

我已經審閱您的最佳解決方案Apple內存管理指南

A)

-(NSData *)somefunction2 
{ 
    NSData *data=[[[NSData alloc]init]autorelease]; 
    // fill stuff for nsdata 
    return data; 
} 

-(void)somefunction 
{  
NSData *data=[self somefunction2];  
// use data  
} 

最好的方法但是大部分的博客的建議,以避免自動釋放,所以我使用以下類型

B)

-(NSData *)somefunction2 
{ 
    NSData *data=[[NSData alloc]init]; 
    // fill stuff for nsdata 
    return data; 
} 

-(void)somefunction 
{ 

NSData *data=[[self somefunction2] retain]; 

// use data 

[data release]; 

} 

C)

-(NSData *)somefunction2 
{ 
    NSData *data=[[[NSData alloc]init]autorelease]; 
    // fill stuff for nsdata 
    return data; 
} 

-(void)somefunction 
{ 

NSData *data=[[self somefunction2] retain]; 

// use data 

[data release]; 

} 

編輯: 一兩件事。如果我嘗試將相同的分配對象傳遞給某個函數調用參數或自定義委託對象,那麼我必須釋放????無論是在函數調用下還是在函數def中獲得保留然後釋放。

NSData *data=[[NSData alloc]init]; 

[self somfunctioncall:data]; 

NSData *data=[[NSData alloc]init]; 

[delegate mydelegatefunction:data]; 


-(void)somfunctioncall:(NSdata *)data 
{ 
NSData *newdata =[data retain]; 
//data use 
[data release];} 

在此先感謝

+1

N.B.前綴「get」僅用於間接返回值或對象的方法。 – albertamg

+0

謝謝albertamg –

回答

3

最好的做法是,如果該方法中包含兩種alloc, init, new or retain,該方法返回一個retained對象,如果沒有它返回一個autoreleased對象。我建議這樣的:

-(NSString *)newData 
{ 
    NSData *data=[[NSData alloc]init]; 
    // fill stuff for nsdata 
    return data; 
} 

這樣以後就可以做這個:

-(void)somefunction 
{ 

NSData *data=[self newData]; 

// use data 

[data release]; 

} 
+0

:謝謝你的回覆。如何在線數據NSData * data = [self getData];將獲得所有權??。我認爲我們需要保留所有權。 –

+0

@Asta ni enohpi,你需要保留它的所有權,但是這種方法是爲你做的 –

+0

內存管理規則規定返回保留對象**的方法以**「alloc」,「new」,「copy 「或」mutableCopy「,而不是它們*包含*它們。此外,方法名稱爲camel case,這意味着「copyRightNotice」返回保留的對象,而「copyrightNotice」不會(後者以「版權」一詞開頭,而前者以「copy」一詞開頭)。 – albertamg

1

我個人比較喜歡第三(C)的方式。但是,在someFunction中沒有必要保留和發佈data

+0

如果你打算使用它,你不應該保留它嗎?在某些功能使用它之前,游泳池是否有可能被排空? –

+1

除非他必須訪問方法外的對象,否則不需要保留它。而且,據我所知,在該方法執行結束之前,自動釋放池不會被排空。 – EmptyStack

2

iOS內存管理有時可能會讓人迷惑!首先,我建議你總是在XCode中運行分析器,它會指出可能的內存泄漏,這可能非常有用!

由於數據是一個局部變量,我相信這是默認情況下兩個函數中的autorelease。

我明白奧斯卡已經給了你一些改進的代碼,那也是我會投票贊成的代碼。

+0

感謝艾倫摩爾..如果我不使用自動釋放,分析儀顯示一些泄漏。 –

+0

在這種情況下,我會繼續做一個[數據發佈]。我個人並不使用autorelease,我同意你閱讀過的其他博客。 –

+0

感謝Alan Moore。+1分析器工具提示 –

0

「A」是正確的。在iOS中避免autorelease的建議是關於在單個方法內管理對象的使用壽命的性能增強,而不是跨越方法的

1

A很好。您返回創建一個對象並返回一個自動釋放對象。另一個函數使用這個對象,並且因爲它不需要保留或釋放它,所以它不需要通過該方法。

沒有錯在正確的地方使用autorelease。在名稱中沒有new,alloc的方法返回自動釋放的對象,所以可以返回getData(這是一個命名錯誤,但現在讓我們離開)的自動釋放對象。

autorelease不鼓勵在其他地方使用,因爲它會增加內存的高水位標記。當它被懶惰地使用時會被錯誤地使用 - 程序員不確定何時可以安全地釋放擁有的對象,所以他們只是自動釋放它們。

+0

感謝您的明確答案,並找到我的錯誤。作爲getdata名稱,現在我已經編輯name.am經常使用以上概念.so autorelease是否會影響我的代碼性能。 PLZ指導我。我認真讀了很多博客。所有的PPL使用不同的風格。 –

+0

你的最後一句話突然讓我明白爲什麼這麼多人建議避免'autorelease'。 EW。但是,謝謝。 :) –

0

請勿避免autorelease

如果博客告訴你要避免autorelease他們給你的建議不好。這是過早的性能優化。使用autorelease可以獲得更簡單的代碼,並且幾乎不會損害性能。而且它幾次確實對造成傷害,這很容易修復。

「A」是正確的。

「B」不正確,因爲它不遵循Objective-C命名約定。這很重要。很多。在學習Objective-C規範時,您會發現很難集成這些代碼。編譯器可能會給你錯誤的警告。而下一版本的llvm將具有自動引用計數,這意味着您可以依靠編譯器爲您的Objective-C對象編寫內存管理代碼。它是基於約定的,所以它會失敗。

「C」也是正確的,但在這種情況下不必要的複雜。如果您在處理數據時有可能會耗盡自動釋放池,這將是正確的代碼。

+0

另外 - 不要依賴ARC來讓所有的內存管理問題消失。它只適用於Objective-C對象,因此您仍然需要自己管理從C API(CoreGraphics,CoreFoundation,GCD等)返回的對象。 – Abizern

+0

好點。稍微調整了我的答案。我沒有解釋C API,但現在我正確地將ARC限制爲Objective-C對象。 –

相關問題