假设我在循环中有以下内容:
for i in 0...10 {
autoreleasepool {
// do some crazy memory thing
}
}
我该如何从autoreleasepool
块中打破for循环?
答案 0 :(得分:2)
为此,我想到的解决方案是从autoreleasepool
块返回一个布尔值,true
继续或false
中断。 autoreleasepool
块显然正在阻塞。
for i in 0...10 {
if (
!autoreleasepool {
// do stuff
// return false for break, true for continue.
return true
}
) {
break
}
}
答案 1 :(得分:2)
设置一个变量,您可以选择在自动释放池中设置该变量:
for i in 0...10 {
var stop = false
autoreleasepool {
// lots of stuff
stop = true // call this if you need to stop
}
if stop { break }
}
答案 2 :(得分:2)
我推断这个问题的目的是能够发布答案,从而显示autoreleasepool
实际上是一个通用方法,返回其闭包返回的任何值。有人建议可以这样做:
for i in 0...10 {
if (
!autoreleasepool {
// do stuff
// return false for break, true for continue.
return true
}
) {
break
}
}
当我们首先发现许多同步关闭方法实际上是返回关闭操作所用的泛型时,这是很令人欣慰的,但我认为这并不是其应用的一个特别好的例子。如果您需要在代码中添加注释以说明返回值的含义,则该代码会带来更深层次的问题。我认为rmaddy’s approach(+1)更清晰,更容易推理。 autoreleasepool
返回与闭包相同的Result
很有用,但是,恕我直言。
让我们考虑使用更引人注目的autoreleasepool
返回类型。假设您有一个执行以下操作的例程(我删除了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)
}
}
这不仅更加简洁,而且清楚说明了自动释放对象的创建位置。这种模式让我很自然地并且很吸引人地使用了autoreleasepool
的行为,即返回其闭包返回的对象。