9

如果没有自动释放池,我正在尝试捕捉场景。
这是我的测试应用程序。

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    [self performSelectorInBackground:@selector(bgOperation:) withObject:nil];
}

- (void)bgOperation:(id)obj
{
    NSString *string [[[NSString alloc] init] autorelease];
}

我试过设置断点 objc_autoreleaseNoPool。
我尝试过使用 Instruments / Leaks 进行分析。
OSX 10.7.5 XCode 4.3.3 以 10.6 为目标,AutomaticRefCounting = NO,GarbageCollection = 不支持。

我了解 NSApplication 包括它自己的自动释放池。但我的理解是每次调用 performSelectorInBackground: 都需要它自己的自动释放池。

来自建议的更新:我 在 main.m 中
尝试过这个..没有运气。

int main(int argc, char *argv[])
{
    NSString *junk = [[[NSString alloc]init]autorelease];
    return NSApplicationMain(argc, (const char **)argv);
}

而这个..
在我的appDelegate中,也没有结果。

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    [NSThread detachNewThreadSelector:@selector(bgOperation:)
                             toTarget:self
                           withObject:nil];
}

而这个..
在我的 main.m 中使用 pthreads

void *doJunk(void *ptr){
  NSString *junk = [[[NSString alloc]initWithString:@"string with no pool"]autorelease];
  NSLog(@"%@", junk);
  pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
  pthread_t thread;
  pthread_create(&thread, NULL, doJunk, NULL);
  return NSApplicationMain(argc, (const char **)argv);
}

我知道由于操作系统级别可能没有任何泄漏(仍未确认),但是当我瞄准 10.6 时,我在日志中看到许多“无池”消息。如果它只是由于操作系统级别而泄漏,那么当我的目标是 10.6 但使用 10.7 SDK 时,我需要一种方法来在 10.7 中捕获这些场景。

4

2 回答 2

5

performSelectorInBackground:现在可能正在使用 dispatch_queue,它会自动为您设置一个自动释放池。尝试直接启动一个新的 NSThread,看看是否会导致泄漏。

您也可以尝试将代码移到 NSApplicationMain 之前,这将具有相同的行为。

于 2012-12-19T17:50:59.117 回答
1

根据文档,在这种情况下仍然必须创建一个池。

performSelectorInBackground:withObject:方法创建一个新的分离线程,并使用指定的方法作为新线程的入口点。

[...]

调用该方法的效果与调用NSThread的detachNewThreadSelector:toTarget:withObject:方法的效果是一样的,参数是当前对象、选择器和参数对象。使用默认配置立即生成新线程并开始运行。在选择器内部,您必须像配置任何线程一样配置线程。例如,如果您打算使用它,您将需要设置一个自动释放池(如果您没有使用垃圾收集)并配置线程的运行循环。

然后根据for的文档NSThread

+ (void)detachNewThreadSelector:(SEL)aSelector
                       toTarget:(id)aTarget
                     withObject:(id)anArgument

对于非垃圾收集的应用程序,方法 aSelector负责为新分离的线程设置一个自动释放池,并在它退出之前释放该池。

因此,除非Apple在没有记录的情况下更改了实现(非常不可能),否则对于在使用autorelease.

为了验证文档是否在陈述事实,请尝试替换您的电话

[self performSelectorInBackground:@selector(bgOperation:) withObject:nil];

[NSThread detachNewThreadSelector:@selector(bgOperation:) toTarget:self withObject:nil];

根据文档,上述两个调用应该是等效的。你可能会发现它们不是。

于 2012-12-30T14:56:02.217 回答