1

我已經看了一下,但一直無法找到這個問題的明確答案。Objective-c異步內存管理

如果我有一個類執行異步操作,何時以及如何釋放它?

-(void)main 
{ 
    AsyncObject *async = [[AsyncObject alloc] initWithDelegate:self]; 

    [async goDoSomething]; 
} 

-(void)didSomething:(Result*)result 
{ 

} 

何時發佈* async?

回答

0

感謝您的幫助球員,我做了一些嘗試使用NSURLConnection來查看它是如何處理它的(當你自動釋放它,它將繼續它的異步操作)。

在每個異步步驟開始時,內部碰到其保留計數,並在每個異步步驟結束時內部釋放自身。

這意味着它可以發送autorelease/release,並且在它完成當前操作之前它不會被釋放。

// MAIN.M 

-(void)main 
{ 
    AsyncObject *async = [[[AsyncObject alloc] initWithDelegate:self] autorelease]; 

    [async goDoSomething]; 
} 

-(void)didSomething:(Result*)result 
{ 

} 

// ASYNCOBJECT.M 

-(void) goDoSomething 
{ 
    [self retain]; 
} 

-(void) finishedDoingSomething 
{ 
    [delegate didSomething:result]; 
    [self release] 
} 
+0

要小心。在這種情況下,您正在泄漏異步,因爲您(1)分配它,然後(2)保留它。你只發布一次。 – csano

+0

那麼不,調用者仍然負責通過自己的機制釋放它或調用autorelease。在內部,我碰到在每個異步操作的開始/結束時刪除保留。它純粹是爲了確保異步操作不會中途失敗,並將其與應用程序一起使用。它還爲調用者釋放它提供了一種便捷的方式(因爲autorelease現在具有所需的效果)。編輯:對不起,我看到我錯過了我的示例autorelease。已添加它。 – Tyler

2

您可以保留一個私有屬性來保存該值,或者,如果您可以控制AsyncObject,則通過didSomething:選擇器中的實例。 我認爲第一個選項更好,因爲您知道該對象將保留,直到您接到委託電話。

選項1:

ClassName.m

@interface ClassName() 
    @property (nonatomic, retain) AsyncObject* async; 
@end 

@interface 
//... 

-(void)main 
{ 
async = [[AsyncObject alloc] initWithDelegate:self]; 

[async goDoSomething]; 
} 

-(void)didSomething:(Result*)result 
{ 
    [async release]; 
    async = nil; 
} 

選項2:

-(void)aysncObject:(AsyncObject*)async didSomething:(Result*)result { 
    [async release]; 
} 
1

如果你的對象運行於後臺線程的異步任務,或者是一個計時器的目標,或者使用GCD並在被調度塊(^ {} kerjigger)的範圍內被引用,那麼它將在該後臺操作的生命週期中保留給你。

所以正常使用情況將是:現在

AsyncObject *async = [[AsyncObject alloc] initWithDelegate:self]; 
[async goDoSomething]; 
[async release]; 

,有可能在後臺工作,對象是留存(例如,通過使用__block -scoped參考對象與GCD,或者用pthread代替你的工作線程而不是NSThread/NSOperation),但是沒有典型的使用情況,我可以想不到會發生什麼。在這種情況下,您應確保-goDoSomething在操作期間內部保留並釋放self

(如果有人能想到該對象未保留您的情況,請發表在評論中,我會更新我的答案。)