2010-04-23 61 views
8

我需要調用一個方法來啓動一些異步代碼Objective-C:如何正確使用內存管理進行異步方法

MyClass* myClass = [[MyClass alloc] init]; 
[myClass startAsynchronousCode]; 

現在我不能簡單地釋放它,因爲這會導致錯誤,因爲代碼仍在運行:

[myClass release]; // causes an error 

最好的方法是什麼處理記憶?

回答

4

你可以有 - [MyClass的startAsynchronousCode]調用回調:

typedef void(*DoneCallback)(void *); 

-(void) startAsynchronousCode { 
    // Lots of stuff 
    if (finishedCallback) { 
    finishedCallback(self); 
    } 
} 

然後實例這樣的MyClass的:

MyClass *myClass = [[MyClass alloc] initWith: myCallback]; 

myCallBack函數可能是這樣的:

void myCallback(void *userInfo) { 
    MyClass *thing = (MyClass *)userInfo; 
    // Do stuff 
    [thing release]; 
} 
+1

當「myCallBack函數」的方法不會結束代碼返回到調用回調方法的結束的執行:「startAsynchronousCode '剛剛被放棄? – Robert 2010-04-23 13:42:01

+1

是的,這就是爲什麼在調用回調之前真的完成這一點很重要。你不會得到任何訪問違規,除非你在回調後提到自己。 – 2010-04-23 14:06:27

+1

我想你在問「startAsynchronousCode如何異步?」在你的評論?上述習慣用法用於創建線程並在該新線程中運行startAsynchronousCode。 – 2010-04-23 14:41:58

0

我一直都在維護一個指向異步對象的實例變量。

- (id)init { 
    myClass = [[MyClass alloc] init]; 
    [myClass startAsynchronousCode]; 
} 

- (void)myClassDidFinish:(MyClass *)myClass { 
    [myClass release]; 
} 
1

您必須在startAsynchronousCode方法內部保留您的myClass對象。完成後,也會在內部釋放它。

此行爲用於NSURLConnection,UIAlertView和其他異步對象。

3

你是如何調用異步代碼?如果使用NSThread +detachNewThreadSelector:toTarget:withObject:,則會發現目標對象被線程保留,直到它終止並釋放。所以你可以在異步消息之後立即釋放對象。

例如

@implementation MyClass 

-(void) startAsynchronousCode 
{ 
    [NSThread detachNewThreadSelector: @selector(threadMain:) toTarget: self withObject: nil]; 
} 

-(void) threadMain: (id) anObject 
{ 
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 
    // do stuff 
    [pool drain]; 
} 
@end 

利用上述,下面的代碼是完全安全的:

MyClass* myClass = [[MyClass alloc] init]; 
[myClass startAsynchronousCode]; 
[myClass release]; 
+0

這是非常有幫助...謝謝。 – jfalexvijay 2011-03-07 12:34:32

相關問題