Swift 从自动释放池中退出循环?

Swift exit for loop from within an autoreleasepool?

假设我在循环中有以下内容:

for i in 0...10 {
    autoreleasepool {
        // do some crazy memory thing
    }
}

我该如何从 autoreleasepool 块中跳出 for 循环?

我为此找到的解决方案是从 autoreleasepool 块中 return 一个布尔值,true 表示继续或 false 表示中断。 autoreleasepool 块显然正在阻塞。

for i in 0...10 {
    if (
        !autoreleasepool {
            // do stuff
            // return false for break, true for continue.
            return true
        }
    ) {
        break
    }
}

设置一个变量,您可以选择在自动释放池中设置:

for i in 0...10 {
    var stop = false
    autoreleasepool {
        // lots of stuff

        stop = true // call this if you need to stop
    }
    if stop { break }
}

我推断这个问题的目的是能够 post 一个答案,显示 autoreleasepool 实际上是一个通用方法,returning 任何值是 return 关闭。有人建议可以这样做:

for i in 0...10 {
    if (
        !autoreleasepool {
            // do stuff
            // return false for break, true for continue.
            return true
        }
    ) {
        break
    }
}

虽然当我们第一次发现这些同步闭包方法中的许多实际上都是泛型时,这很有启发性 return 无论闭包做什么,我认为这不是它应用的一个特别好的例子。如果您需要代码中的注释来解释 return 值的含义,那是更深层次问题的代码味道。我认为 (+1) 更清晰,更容易推理。 autoreleasepool return 和闭包一样 Result 有很好的用途,但恕我直言,这不是它。


让我们考虑一个更有说服力的使用 autoreleasepool return 类型。假设您有一些例程执行以下操作(我删除了 GCD 调用以使我们的注意力集中在 autoreleasepool):

func generateAllImages() {
    for index in 0 ..< imageCount {
        let image = generateImage(for: index)
        updateUserInterface(for: index, with: image)
    }
}

假设在分析应用程序的过程中,我们发现隐藏在 generateImage 中的东西创建了一个自动释放对象,这使得我们应用程序的内存使用峰值真正飙升。显然,您可以执行以下操作来降低应用程序的高水位标记,在每次迭代时清空自动释放池:

func generateAllImages() {
    for index in 0 ..< imageCount {
        autoreleasepool {
            let image = generateImage(for: index)
            updateUserInterface(for: index, with: image)
        }
    }
}

但是如果你已经确认你的自动释放对象被限制在 generateImage 例程的范围内,你可以稍微整理一下:

func generateAllImages() {
    for index in 0 ..< imageCount {
        let image = autoreleasepool { generateImage(for: index) }
        updateUserInterface(for: index, with: image)
    }
}

这不仅更简洁,而且清楚地说明了自动释放对象的创建位置。这种模式让我印象深刻,因为它非常自然且令人信服地使用了 returning 对象的 autoreleasepool 行为,它的闭包 returns.