使用[NSThread detachNewThreadSelector:toTarget:withObject:]时如何设置自动释放池

时间:2011-03-18 09:36:09

标签: iphone multithreading ios

您好我正在使用[NSThread detachNewThreadSelector:toTarget:withObject:]并且我收到了大量内存泄漏,因为我没有为分离线程设置自动释放池。我只是想知道我在哪里这么做?是在我打电话之前

[NSThread detachNewThreadSelector:toTarget:withObject:]

或在另一个线程中运行的方法?

任何帮助将不胜感激,一些示例代码将是伟大的。

感谢。

5 个答案:

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