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