【问题标题】:How can we decide whether we should use autoreleasepool?我们如何决定是否应该使用 autoreleasepool?
【发布时间】:2021-10-19 21:49:20
【问题描述】:

由于Apple的API没有开源,文档中也没有提到,所以在用Swift写的时候,我们无法知道返回的对象是不是autoreleaseobjective-c对象。

因此,我们何时应该使用autoreleasepool变得不清楚

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-1041876

如果你编写一个循环来创建许多临时对象。

您可以在循环内使用自动释放池块来处理 下一次迭代之前的那些对象。使用自动释放池 循环中的块有助于减少最大内存占用 应用。

没有自动释放池

for ... {
    FileManager.default.copyItem
    CGImageSourceCreateWithURL
    CGImageSourceCopyPropertiesAtIndex
    CGImageSourceCreateThumbnailAtIndex
    CGImageDestinationCreateWithURL
    CGImageDestinationFinalize
}

使用自动释放池

for ... {
    autoreleasepool {
        FileManager.default.copyItem
        CGImageSourceCreateWithURL
        CGImageSourceCopyPropertiesAtIndex
        CGImageSourceCreateThumbnailAtIndex
        CGImageDestinationCreateWithURL
        CGImageDestinationFinalize
    }
}

为了比较,我尝试对上述 2 个代码进行密集循环。

根据 XCode 内存报告,我发现他们的内存使用模式没有显着差异

我想知道,有什么好的指导方针/思考过程来决定我们是否应该在整个代码中应用autoreleasepool

我有这样的担忧,因为最近我看到在涉及FileHandle.read的代码中需要autoreleasepool - https://stackoverflow.com/a/42935601/72437

【问题讨论】:

  • 你只需要担心autoreleasepool,如果你在一个紧密的循环中创建大量的大对象而不将控制权交还给事件循环(它负责自动释放) .
  • 没有一个很好的创建自动释放对象的 Cocoa API 列表。它可能会随着时间而改变。那么,什么时候应该使用autoreleasepool?当您分析您的应用程序并看到显着的内存增长时。例如。 stackoverflow.com/questions/25860942/….
  • 顺便说一下,CoreGraphics 调用名称中带有Create(或Copy),见Create Rule,与自动释放对象无关。

标签: ios swift objective-c automatic-ref-counting


【解决方案1】:

使用FileManager 复制项目没有很大的有效负载。而您使用的 Image I/O 将在 I/O 过程中节省大量内存。另外,苹果的图片api会缓存同一个文件。

这就是您的代码不会有显着差异的原因。因为你没有做任何内存负载。

您可以尝试另一种方法来验证autoreleasepool 的使用情况。而且我可以保证它会有很大的不同。

使用for循环(10000次)生成随机字符串(越长越好),并在每个循环中使用每个字符串转换一个UTF-8数据。然后从有或没有autoreleasepool 的情况下查看不同的内存增长情况。

试试看。

【讨论】:

    猜你喜欢
    • 2012-07-11
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    • 1970-01-01
    • 2013-08-11
    相关资源
    最近更新 更多