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。它纯粹是为了确保异步操作不会中途失败,并带走应用程序。它还为调用者提供了一种方便的方式来释放它(因为自动释放现在具有所需的效果)。编辑:对不起,我看我错过了我的样本中的自动释放。我已经添加了它。