您好我正在使用[NSThread detachNewThreadSelector:toTarget:withObject:]并且我收到了大量内存泄漏,因为我没有为分离线程设置自动释放池。我只是想知道我在哪里这么做?是在我打电话之前
[NSThread detachNewThreadSelector:toTarget:withObject:]
或在另一个线程中运行的方法?
任何帮助将不胜感激,一些示例代码将是伟大的。
感谢。
答案 0 :(得分:9)
在你用线程调用的方法中...即给定...
[NSThread detachNewThreadSelector:@selector(doStuff) toTarget:self withObject:nil];
你的方法是......
- (void)doStuff {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//Do stuff
[pool release];
}
答案 1 :(得分:6)
您必须在您调用的方法中设置一个自动释放池,并且将在新的分离线程中执行。
例如:
// Create a new thread, to execute the method myMethod
[NSThread detachNewThreadSelector:@selector(myMethod) toTarget:self withObject:nil];
和
- (void) myMethod {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Here, add your own code
// ...
[pool drain];
}
请注意,我们在autoreleasepool上使用drain而不是release。在iOS上,它没有区别。在Mac OS X上,如果您的应用程序是垃圾回收,它将触发垃圾回收。这使您可以编写可以更轻松地重用的代码。
答案 2 :(得分:5)
创建新主题:
[NSThread detachNewThreadSelector:@selector(myMethod) toTarget:self withObject:nil];
创建新线程调用的方法。
- (void)myMethod
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Your Code
[pool release];
}
如果您需要从新线程内部对主线程执行某些操作(例如,显示加载符号),该怎么办?使用performSelectorOnMainThread。
[self performSelectorOnMainThread:@selector(myMethod) withObject:nil waitUntilDone:false];
参考: - iPhone SDK Examples
答案 3 :(得分:3)
在您调用的方法中执行此操作。从本质上讲,您应该设置被称为自包含工作单元的方法(事实上,它将与通过[NSOperation][1]
或Grand Central Dispatch调用兼容:两种更好的方式组织并行工作)。
但是如果我不能改变我调用新线程的方法的实现呢?
在这种情况下,你会这样做:
[NSThread detachNewThreadSelector: @selector(blah:) toTarget: obj withObject: arg]
这样做:
[NSThread detachNewThreadSelector: @selector(invokeBlah:) toTarget: self withObject: dict]
- (void)invokeBlah: (id)dict {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
id obj = [dict objectForKey: @"target"];
id arg = [dict objectForKey: @"argument"];
[obj blah: arg];
[pool release];
}
而不是使用字典,您还可以创建一个封装远程对象调用的NSInvocation。我刚刚选择了一本字典,因为这是在SO答案中显示情况的最快方式。要么工作。
答案 4 :(得分:3)
文档说明在线程中运行的方法必须创建并销毁自己的自动释放池。所以如果你的代码有
[NSThread detachNewThreadSelector:@selector(doThings) toTarget:self withObject:nil];
方法应该是
- (void)doThings {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//Do your things here
[pool release];
}