首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >嵌套的NSAutoreleasePool

嵌套的NSAutoreleasePool
EN

Stack Overflow用户
提问于 2010-11-24 21:13:29
回答 1查看 745关注 0票数 0

在我的一个ipad应用程序中,我正在使用json字符串远程构建数据库,然后将其转换为NSArray以插入到核心数据中,然后在iPad上加载大约600Mb的图像。所有这些都是在后台线程中创建的,从一开始就会导致一些内存问题。我掌握了在操作中嵌套3个不同的NSAutoreleasePool并在方便的时候释放它们的问题。我没有得到错误,也没有泄漏,也没有警告。我只是想知道这是不是一个好的方法,或者我只是错过了一些东西。

下面是一个示意性的例子(真实的代码很长):

代码语言:javascript
复制
- (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) {

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-11-24 23:57:57

我很惊讶你的代码没有崩溃。在引用计数环境中,-drain的行为与-release相同,因此下面的命令会释放池

代码语言:javascript
复制
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集合中只有一个对象。你需要这样做:

代码语言:javascript
复制
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块中排空最外层的池,以便在引发异常时不会跳过它,即您应该这样做:

代码语言:javascript
复制
- (void)main{

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // first pool

    @try {

        // Do al your stuff
    }
    @catch (NSException * e) {

    }
    @finally
    {
        [pool drain];
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4267158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档