IPhone SDK - 使用performSelectorInBackground泄漏内存

时间:2010-03-14 10:43:55

标签: iphone memory-leaks

也许有人可以帮我解决这个奇怪的事情:

如果用户点击按钮,则会将新的UITableView推送到导航控制器。这个新视图正在进行一些数据库查询,这需要一些时间。因此我想在后台进行加载。

什么有效,没有泄漏内存(但冻结屏幕直到一切都完成):

WorkController *tmp=[[WorkController alloc] initWithStyle:UITableViewStyleGrouped];
self.workController=tmp;
[tmp release];

[self.workController loadList]; // Does the DB Query
[self.workController pushViewController:self.workController animated:YES];  

现在我试着这样做:

    // Show Wait indicator
    ....

    WorkController *tmp=[[WorkController alloc] initWithStyle:UITableViewStyleGrouped];
    self.workController=tmp;
    [tmp release];

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

-(void) getController {
    [self.workController loadList]; // Does the DB Query
    [self.navigationController pushViewController:self.workController animated:YES];
}

这也有效,但是内存泄漏,我不知道为什么! 你能帮忙吗?

顺便说一下 - 应用程序是否可能因内存泄漏而进入AppStore?或者首先要检查这个?

提前致谢!

2 个答案:

答案 0 :(得分:5)

不,小内存泄漏(最有可能)您的应用程序不会被appstore拒绝。

在您的示例中,当您在单独的线程中运行方法时,您应该为该线程创建并处置NSAutoreleasePool对象以处理自动释放的对象。对getController方法进行更改应该可以解决问题:

-(void) getController {
    NSAutoreleasedPool *pool = [[NSAutoreleasedPool alloc] init];

    [self.workController loadList]; // Does the DB Query
    [self.navigationController pushViewController:self.workController animated:YES];

    [pool release];
}

有关详细信息,请参阅内存管理指南中的Autorelease Pools部分。那里的相关引言:

  

如果你产生了一个辅助线程,那么你   必须创建自己的自动释放池   一旦线程开始   执行;否则,你会泄漏   对象。 (有关详细信息,请参阅“Autorelease Pools and Threads”。)

答案 1 :(得分:0)

顺便说一句,你是从后台线程调用pushViewController:。这很糟糕。

你应该只对UI做一些事情 - 比如从主线程中推送视图控制器和更改UI项目。如果你不这样做,事情就会破裂。

请参阅“Cocoa基础指南”中标题为“Cocoa框架线程是否安全?”的部分:它说“所有UIKit对象只应在主线程上使用。”