在我的一个ipad应用程序中,我正在使用json字符串远程构建数据库,然后将其转换为NSArray以插入到核心数据中,然后在iPad上加载大约600Mb的图像。所有这些都是在后台线程中创建的,从一开始就会导致一些内存问题。我掌握了在操作中嵌套3个不同的NSAutoreleasePool并在方便的时候释放它们的问题。我没有得到错误,也没有泄漏,也没有警告。我只是想知道这是不是一个好的方法,或者我只是错过了一些东西。
下面是一个示意性的例子(真实的代码很长):
- (void)main{
@try {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // first pool
[managedOC lock];
NSArray *results = [self loadEntitiesWithGroupName:@"Project" andName:@"projects"];
NSAutoreleasePool *prjPool; // second pool
for (NSDictionary *thisResult in results) {
prjPool = [[NSAutoreleasePool alloc] init];
Project *prj = [[Project alloc] initWithEntity:[NSEntityDescription entityForName:@"Project" inManagedObjectContext:self.managedOC] insertIntoManagedObjectContext:self.managedOC];
prj.name = [thisResult objectForKey:@"name"];
[prj saveThumbnail:[thisResult objectForKey:@"thumbnail"]];
//Slides. Those are the images that take so mutch space.
NSArray *slides = [thisResult objectForKey:@"slides"];
NSAutoreleasePool *slidePool; // third pool
if(slides != kCFNull){
slidePool = [[NSAutoreleasePool alloc] init];
for(NSDictionary *slide in slides){
Slide *thisSlide = [[Slide alloc] initWithEntity:[NSEntityDescription entityForName:@"Slide" inManagedObjectContext:self.managedOC] insertIntoManagedObjectContext: self.managedOC];
thisSlide.path = prj.path;
[thisSlide saveFile:[slide objectForKey:@"file"]];
[prj addSlidesObject:thisSlide];
[thisSlide release];
[slidePool drain];
}
}
[prj release];
[result release];
[prjPool drain];
}
[self.managedOC unlock];
[totResult release];
[pool drain];
}
@catch (NSException * e) {
}发布于 2010-11-24 23:57:57
我很惊讶你的代码没有崩溃。在引用计数环境中,-drain的行为与-release相同,因此下面的命令会释放池
slidePool = [[NSAutoreleasePool alloc] init]; // this is in the wrong place
for(NSDictionary *slide in slides){
Slide *thisSlide = [[Slide alloc] initWithEntity:[NSEntityDescription entityForName:@"Slide" inManagedObjectContext:self.managedOC] insertIntoManagedObjectContext: self.managedOC];
thisSlide.path = prj.path;
[thisSlide saveFile:[slide objectForKey:@"file"]];
[prj addSlidesObject:thisSlide];
[thisSlide release];
[slidePool drain];
}除非slides集合中只有一个对象。你需要这样做:
for(NSDictionary *slide in slides){
slidePool = [[NSAutoreleasePool alloc] init]; // this is in the right place
Slide *thisSlide = [[Slide alloc] initWithEntity:[NSEntityDescription entityForName:@"Slide" inManagedObjectContext:self.managedOC] insertIntoManagedObjectContext: self.managedOC];
thisSlide.path = prj.path;
[thisSlide saveFile:[slide objectForKey:@"file"]];
[prj addSlidesObject:thisSlide];
[thisSlide release];
[slidePool drain];
}除此之外,你还有一个正确的总体思路。
您应该在异常处理程序的finally块中排空最外层的池,以便在引发异常时不会跳过它,即您应该这样做:
- (void)main{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // first pool
@try {
// Do al your stuff
}
@catch (NSException * e) {
}
@finally
{
[pool drain];
}
}https://stackoverflow.com/questions/4267158
复制相似问题