代码之家  ›  专栏  ›  技术社区  ›  Robert MouzmiSadiq

Objective-C:如何正确使用异步方法的内存管理

  •  8
  • Robert MouzmiSadiq  · 技术社区  · 15 年前

    我需要调用一个方法来启动一些异步代码

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

    现在我不能简单地释放它,因为这会导致错误,因为代码仍在运行:

    [myClass release];  // causes an error
    

    处理记忆的最好方法是什么?

    4 回复  |  直到 7 年前
        1
  •  4
  •   Frank Shearar    15 年前

    您可以-[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];
    }
    
        2
  •  3
  •   Frank Shearar    15 年前

    如何调用异步代码?如果你使用 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];
    
        3
  •  1
  •   Skie    15 年前

    此行为用于NSURLConnection、UIAlertView和其他异步对象。

        4
  •  0
  •   kubi    15 年前

    我一直在维护一个指向异步对象的实例变量。

    - (id)init {
        myClass = [[MyClass alloc] init];
        [myClass startAsynchronousCode];
    }
    
    - (void)myClassDidFinish:(MyClass *)myClass {
        [myClass release];
    }