Objective-c异步内存管理

Objective-c异步内存管理,objective-c,ios,memory-management,memory-leaks,asynchronous,Objective C,Ios,Memory Management,Memory Leaks,Asynchronous,我环顾了一下四周,但找不到这个问题的确切答案 如果我有一个执行异步操作的类,那么何时以及如何释放它 -(void)main { AsyncObject *async = [[AsyncObject alloc] initWithDelegate:self]; [async goDoSomething]; } -(void)didSomething:(Result*)result { } 何时释放*async?您可以保留一个私有属性来保存该值,或者,如果您可以

我环顾了一下四周,但找不到这个问题的确切答案

如果我有一个执行异步操作的类,那么何时以及如何释放它

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

     [async goDoSomething];
}

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

}

何时释放*async?

您可以保留一个私有属性来保存该值,或者,如果您可以控制
异步对象
,则在
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];
}

如果您的对象在后台线程上运行其异步任务,或者是计时器的目标,或者使用GCD,并且在调度块的范围内被引用(
^{}
kerjigger),那么它将为您保留该后台操作的生存期

// 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]
} 
因此,正常使用情况是:

 AsyncObject *async = [[AsyncObject alloc] initWithDelegate:self];
 [async goDoSomething];
 [async release];
现在,可以在后台使用未保留的对象(例如,通过使用带有GCD的对象的
\uu块
-作用域引用,或者通过使用pthreads而不是
NSThread
/
NSOperation
)分离工作线程)但是,我想不出会发生这种情况的典型用例。在这种情况下,您应确保
-goDoSomething
在操作期间在内部保留和释放
self

// 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]
} 

(如果有人能想到一个不为您保留对象的情况,请在评论中发布,我会更新我的答案。)

感谢大家的帮助,我对NSURLConnection进行了一些实验,看看它是如何处理的(当您自动释放该对象时,它将继续进行异步操作)

事实证明,在每个异步步骤开始时,它会在内部增加保留计数,在每个异步步骤结束时,它会在内部释放自己

这意味着它可以被自动释放/释放,并且在完成当前操作之前不会被释放

// 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]
} 

小心。在本例中,由于(1)分配异步,然后(2)保留异步,所以正在泄漏异步。您只释放一次。不,调用方仍然负责通过自己的机制释放它或调用autorelease。在内部,我将在每个异步操作的开始/结束时删除retain。它纯粹是为了确保异步操作不会中途失败,并带走应用程序。它还为调用者提供了一种方便的方式来释放它(因为自动释放现在具有所需的效果)。编辑:对不起,我看我错过了我的样本中的自动释放。我已经添加了它。