2012-12-19 69 views
9

我试图捕捉场景,如果没有autorelease池。
这是我的测试应用程序。AutoreleasePool没有捕捉断点,没有警告,仪器中没有报告泄漏

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

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

我试着设置断点objc_autoreleaseNoPool。
我试着用仪器/泄漏进行分析。
OSX 10.7.5 XCode 4.3.3 Targeting 10.6,AutomaticRefCounting = NO,GarbageCollection = Unsupported。

我知道NSApplication包括它自己的autorelease池。但我的理解是每个调用执行SelectorInBackground:需要它自己的autorelease池。从建议

更新:
我想这个..
在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并行线程

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.7中捕获这些场景,而我的目标是10.6而使用10.7 SDK。

+0

你在寻找日志中的“泄漏”信息吗? –

+0

当我运行应用程序并在10.6中观看控制台时,我只能看到它们。 – estobbart

回答

5

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

你也可以尝试将你的代码移到NSApplicationMain之前,它会有相同的行为。

+0

我读过的所有文档都解释了每个调用performSelectorInBackgroud的过程:需要它自己的自动释放池。这仅适用于某些os级别吗? – estobbart

+0

曾经是真的,但我认为它可能已经改变。 –

+0

[NSThread detachNewThreadSelector:@selector(bgOperation :) toTarget:self withObject:nil];没有效果。 – estobbart

1

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

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

[...]

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

然后根据NSThreaddocumentation

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

对于非垃圾收集应用中,该方法aSelector是负责建立一个自动释放池为新分离线程和释放该池在退出之前。

因此,除非苹果改变的实现,而不记录它(不太可能),创建池仍然强制性在一个单独的线程,这使得使用autorelease执行的任何选择。

为了验证是否是文档说明真相,请尝试使用

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

更换您的通话

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

按照文档上面的两个电话应该是等价的。你可能会发现他们不是。