【问题标题】:Objective-c Async memory managementObjective-c 异步内存管理
【发布时间】:2011-07-10 02:26:00
【问题描述】:

我环顾四周,但无法找到这个问题的明确答案。

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

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

     [async goDoSomething];
}

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

}

我什么时候发布 *async?

【问题讨论】:

    标签: objective-c ios memory-management memory-leaks asynchronous


    【解决方案1】:

    您可以保留一个私有属性来保存该值,或者,如果您可以控制 AsyncObject,则将实例传递到 didSomething: 选择器中。 我认为第一个选项更好,因为您知道该对象将被保留,直到您获得委托调用。

    选项 1:

    类名.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];
    }
    

    【讨论】:

      【解决方案2】:

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

      所以正常的用例是:

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

      现在,可以在后台处理保留的对象(例如,通过使用 GCD 对对象的__block-范围引用,或通过使用pthreads 而不是NSThread/NSOperation),但是我没有想到会发生这种情况的典型用例。在这种情况下,您应该确保-goDoSomething 在内部保留并在操作期间释放self

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

      【讨论】:

        【解决方案3】:

        感谢各位的帮助,我对 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 现在具有预期的效果)。编辑:对不起,我看到我错过了示例中的自动释放。已添加。
        猜你喜欢
        • 2020-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多