也许有人可以帮我解决这个奇怪的事情:
如果用户点击按钮,则会将新的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?或者首先要检查这个?
提前致谢!
答案 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对象只应在主线程上使用。”