需要有关@autoreleasepool的帮助

S.J*_*S.J 2 objective-c nsautoreleasepool ios

关于@autoreleasepool的高级内存管理编程指南说:

使用本地自动释放池块来减少峰值内存占用量

许多程序创建自动释放的临时对象.这些对象会添加到程序的内存占用空间,直到块结束.在许多情况下,允许临时对象累积直到当前事件循环迭代结束时不会导致过多的开销; 但是,在某些情况下,您可能会创建大量临时对象,这些对象会大大增加内存占用,并且您希望更快地处置.在后面这些情况下,您可以创建自己的自动释放池块.在块结束时,临时对象被释放,这通常导致它们的释放,从而减少程序的内存占用.

以下示例显示了如何在for循环中使用本地自动释放池块.

NSArray *urls = <# An array of file URLs #>;
for (NSURL *url in urls) {

    @autoreleasepool {
        NSError *error;
        NSString *fileContents = [NSString stringWithContentsOfURL:url
                                         encoding:NSUTF8StringEncoding error:&error];
        /* Process the string, creating and autoreleasing more objects. */
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码也可以在没有autoreleasepool的情况下编写并有效管理吗?

比如在处理它之后创建property of fileContents并设置nil它.

self.filecontents = nil;
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 5

问题是stringWithContentsOfURL可以返回一个自动释放的对象.但你可以 initWithContentsOfURL改用:

NSArray *urls = <# An array of file URLs #>;
for (NSURL *url in urls) {
    NSError *error;
    NSString *fileContents = [[NSString alloc] initWithContentsOfURL:url
                                     encoding:NSUTF8StringEncoding error:&error];
    /* Process the string ... */
    fileContents = nil;
}
Run Code Online (Sandbox Code Playgroud)

init...方法返回一个(+1)保留对象而不是一个自动释放的对象,因此 fileContents = nil释放该对象并销毁它(如果没有其他强引用).

当然,只有当"字符串处理代码"不产生其他自动释放的对象时,这才有用.(另外error,如果设置,将是一个自动释放的对象.)

(实际上它不会"保证" stringWithContentsOfURL返回自动释放的对象.特别是在发布模式下,ARC编译器会删除许多不必要的保留/自动释放/释放操作.)

我不知道建立一个本地自动释放池是否是一个昂贵的操作(我假设没有).如果您在循环中处理许多对象并且您不确切地知道是否创建了自动释放的对象,那么仅使用本地自动释放池并"不关心它"可能是明智的.使用"仪器"进行分析也可以提供更多洞察力.

有关更多信息,请参阅Clang ARC文档中的"保留的返回值"和"未保留的返回值" .