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

时间:2022-09-07 08:26:14

I need to call a method that starts some asynchronous code

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

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

Now I cant simply release it as this would cause an error since the code is still running:

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

[myClass release];  // causes an error

What is the best way to deal with the memory?

处理内存的最佳方法是什么?

4 个解决方案

#1


4  

You could have -[MyClass startAsynchronousCode] invoke a callback:

你可以 - [MyClass startAsynchronousCode]调用一个回调:

typedef void(*DoneCallback)(void *);

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

and then instantiate a MyClass like this:

然后像这样实例化一个MyClass:

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

myCallback might look like this:

myCallback可能如下所示:

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

#2


3  

How are you invoking the asynchronous code? If you use NSThread +detachNewThreadSelector:toTarget:withObject:, you'll find that the target object is retained by the thread until it terminates and then it is released. So you can release the object immediately after the asynchronous message.

你是如何调用异步代码的?如果你使用NSThread + detachNewThreadSelector:toTarget:withObject:,你会发现目标对象被线程保留,直到它终止然后被释放。因此,您可以在异步消息之后立即释放该对象。

e.g.

@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

With the above, the following code is perfectly safe:

有了上述代码,以下代码非常安全:

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

#3


1  

You must retain your myClass object internally in startAsynchronousCode method. And release it internally too after it finished.

您必须在startAsynchronousCode方法内部保留myClass对象。完成后也会在内部发布。

This behavior used in NSURLConnection, UIAlertView and other async objects.

此行为在NSURLConnection,UIAlertView和其他异步对象中使用。

#4


0  

What I've always done is maintained an instance variable that points to the asynchronous object.

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

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

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

#1


4  

You could have -[MyClass startAsynchronousCode] invoke a callback:

你可以 - [MyClass startAsynchronousCode]调用一个回调:

typedef void(*DoneCallback)(void *);

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

and then instantiate a MyClass like this:

然后像这样实例化一个MyClass:

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

myCallback might look like this:

myCallback可能如下所示:

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

#2


3  

How are you invoking the asynchronous code? If you use NSThread +detachNewThreadSelector:toTarget:withObject:, you'll find that the target object is retained by the thread until it terminates and then it is released. So you can release the object immediately after the asynchronous message.

你是如何调用异步代码的?如果你使用NSThread + detachNewThreadSelector:toTarget:withObject:,你会发现目标对象被线程保留,直到它终止然后被释放。因此,您可以在异步消息之后立即释放该对象。

e.g.

@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

With the above, the following code is perfectly safe:

有了上述代码,以下代码非常安全:

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

#3


1  

You must retain your myClass object internally in startAsynchronousCode method. And release it internally too after it finished.

您必须在startAsynchronousCode方法内部保留myClass对象。完成后也会在内部发布。

This behavior used in NSURLConnection, UIAlertView and other async objects.

此行为在NSURLConnection,UIAlertView和其他异步对象中使用。

#4


0  

What I've always done is maintained an instance variable that points to the asynchronous object.

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

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

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