iphone:threads + release pool + [object release] =“发送给deallocated instance的消息”

时间:2010-09-08 17:12:42

标签: iphone objective-c objective-c++

我在iphone上运行一些小代码时感觉很糟糕。

基本上,我只需按一个按钮,就会调用runTest,它会在后台线程上运行test方法。这就是我创建自动释放池的原因。

如果我运行以下代码,我在控制台上收到一条漂亮的消息说:
2010-09-07 11:45:15.527 test[1312:207] *** -[CFString release]: message sent to deallocated instance 0x3d52ba0

-(void) test {
    NSAutoreleasePool *apool = [[NSAutoreleasePool alloc] init];

    NSString *xml = [[NSString alloc] initWithFormat:@"<%@>", @"msg"];
    NSLog(@"%@\n",xml);
    [xml release];

    [apool release]; // <-- this line throws the error msg  
}

- (IBAction) runTest: (id)sender
{
    [self performSelectorInBackground:@selector(test) withObject:nil];

}

我发现:如果我没有在后台线程(没有自动释放池)上运行test,只需调用[self test],代码就可以了。

所以,我认为问题出在线程+自动释放池周围,我做错了什么?我怎么解决呢?

P.S。我启用了NSZombie标记。

3 个答案:

答案 0 :(得分:0)

NSLog可能必须向UI线程发送消息(在主线程上执行选择器)以打印序列化到控制台,到那时,您的xml已经被释放。

答案 1 :(得分:0)

在这种情况下无关紧要,但您应始终drain池,而不是release它们。

这是一个真正奇怪的错误,如果这是所有的代码。

我建议的第一件事是在记录仪器中的所有保留/释放事件时运行启用了僵尸检测的代码。这将为您提供有关违规对象的保留/释放清单。如果结果仍然没有意义,请发布结果。

答案 2 :(得分:0)

您是否尝试过对象-autorelease上的xml?这会将其添加到活动池apool。声明drain比声明-release更好 - 它们在非垃圾收集环境中是相同的,但有一天Apple可能会在iPhone上实现垃圾收集。希望这会有所帮助。