2010-09-08 125 views
2

我在iPhone上运行一些小代码的时间很糟糕。iphone:线程+发布池+ [object release] =“发送到释放实例的消息”

基本上,我只是按下一个按钮,它调用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],代码工作正常。

所以,我认为问题是围绕线程+ autorelease池,我做错了什么?我该如何解决它?

P.S.我已启用NSZombie标志。

+0

我用上面给出的确切代码创建了一个简单的测试用例应用程序,它可以正常工作,并且没有错误。更可能有一些你省略的代码是罪魁祸首。 – 2010-09-08 18:18:16

+0

快速问题:为什么你需要这里的autorelease池? – jrtc27 2010-09-08 18:45:47

+0

使用Cocoa或iOS Objective-C API时,您总是需要一个自动释放池。在自己进行线程化时,您必须手动管理池。 – bbum 2010-09-08 19:52:14

回答

0

NSLog可能需要向UI线程发送一条消息(在主线程上执行选择器)以便序列化到控制台,届时,xml已经发布。

+0

有趣,我删除:'NSLog(@“%@ \ n”,xml);'问题依然存在 ' – jhon 2010-09-08 17:44:38

+0

好猜,但错误 - NSLog在任何被调用的线程上执行它的事情。 – bbum 2010-09-08 17:58:57

0

它在这种情况下应该没有关系,但你应该永远drain池,从来没有release他们。

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

我建议的第一件事是在启用僵尸检测的同时运行代码,同时在乐器中记录所有保留/释放事件。这会给你一个保留/释放违规对象的清单。发布结果,如果它仍然没有意义。

0

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

相关问题