@autoreleasepool 在我的场景和 ARC 中是不是有意义?

Posted

技术标签:

【中文标题】@autoreleasepool 在我的场景和 ARC 中是不是有意义?【英文标题】:Does @autoreleasepool make sense in my scenario and in ARC?@autoreleasepool 在我的场景和 ARC 中是否有意义? 【发布时间】:2015-09-26 10:58:14 【问题描述】:

我解析文件的内容以便在上下文中创建一组NSManagedObject 并保存它们。这是我这样做的方法:

- (BOOL)getEntitiesFromFileInContext:(NSManagedObjectContext *)context

   BOOL result = YES;
   NSMutableArray *entities = [[NSMutableArray alloc] init];

   NSString *entitiesFileContent = [FilesManagerHelper readFile:fileName];

   if ([entitiesFileContent isEqualToString:@""]) 
       result = NO;
   
   else 
       @autoreleasepool 
           entities = [self parseEntitiesFileContent:entitiesFileContent inContext:context];

           // If entities.count > 0, some operations here
       

       // Save context and reset
       [self saveContext:context];
       [self clearContext:context];
   

   return result;

parseEntitiesFileContent:inContext: 方法中,我将NSManagedObject 对象插入到我提供的上下文中,并将它们添加到entities 数组中。

我在@autoreleasepool 中执行此操作,因为我找到了这样做的示例,但我不确定是否真的有必要...有人可以解释一下使用@autoreleasepool 和不使用之间的区别吗?应该是吧?

非常感谢

编辑:应该在@autoreleasepool 块内定义entities 数组吗?

【问题讨论】:

我希望得到一个静态分析器警告,上面写着“从不读取实体”。我是否遗漏了一些东西 - 此方法范围内的“实体”目的是什么? @Bamsworld 你说得对,我错过了那里的一些代码。编辑了代码sn-p。 【参考方案1】:

因为 entities 是在方法范围内声明的,而不是在 autorelease pool 块中,所以你有一个指向 entities 外部的强指针autorelease pool blockauto release pool 在这种情况下将不起作用。

要验证这一点,请尝试在方法返回之前记录 entities

为了使自动释放池块有一些意义,在自动释放池块中声明entities

@autoreleasepool 
       NSMutableArray *entities = [self parseEntitiesFileContent:entitiesFileContent inContext:context];

       // If entities.count > 0, some operations here
   

现在尝试在自动释放池块之后立即记录 entities

如果 entities 很小,这种情况相当简单,但是包含它也不错,因为它可能有助于可扩展性,因为这种方法可能会随着时间的推移而发展,并且自动释放块开始做更多的事情.如果 entities 可能很大,那么您绝对想要这个池。我的建议是离开自动释放池块并将 entities 的声明移到池块内。

【讨论】:

【参考方案2】:

@autorelase 语句意味着创建一个自动释放池,该池将包含在@autorelease 范围内标记为自动释放的所有对象。因此,使用@autorelease 当且仅当存在相对大量的自​​动释放标记对象时才有意义(不仅需要即时内存释放,还需要避免“内存峰值”)。内存分配和释放是一个需要在一篇文章中解释的大主题,但主要规则是:如果一个范围要包含大量自动释放标记的对象,请使用 @autorelease

【讨论】:

谢谢,所以...我会使用@autorelease 仅当我希望得到一个非常大的文件,其中包含要解析的对象?问题是我事先不知道在这样的文件中有多少对象。保留“@autorelease”块以防万一会更好吗? 您的问题的答案是:“也不完全是”。关于大量数据:如果您使用 1 个 NSData 实例,如果您将数据分配给一个,它将被释放(当您停止使用它时)或由强引用保留。无缘无故地保留@autorelease 范围是一种矫枉过正。这完全取决于您使用了多少“自动释放标记”的对象,以及您计划在范围末端对这些对象做什么。 *** 上已经有丰富的讨论:***.com/questions/9086913/…。希望它会有所帮助。 非常感谢您的解释

以上是关于@autoreleasepool 在我的场景和 ARC 中是不是有意义?的主要内容,如果未能解决你的问题,请参考以下文章

内存管理总结-autoreleasePool

0c-36-自动释放池应用场景

(20)Cocos2d-x中的引用计数(Reference Count)和自动释放池(AutoReleasePool)

iOS开发-34自己主动释放池@autoreleasepool的使用注意事项以及ARC机制——面试必考内容

iOS基础 - autorelease 和 autoreleasepool

iOS基础 - autorelease 和 autoreleasepool