更新
这是一个更简单的复制,不使用数组(h / t到Tim):
func identity<T>(_ v: T) -> T {
return v
}
var closure = {
return
}
while true {
closure()
closure = identity(closure)
}
运行此代码会导致堆栈溢出。我正在向Swift提交一个错误。
原始
原标题:Swift:闭包数组导致EXC_BAD_ACCESS代码= 2
我试图了解为什么此代码生成EXC_BAD_ACCESS代码= 2。这是代码:
var closures: [() -> ()] = []
closures.append({
return
})
while true {
var newClosures: [() -> ()] = []
for closure in closures {
closure()
newClosures.append(closure)
}
closures = newClosures
}
我试图将问题提炼到尽可能少的行,这就是为什么代码可能看起来有点奇怪和毫无意义。 (它唯一的&#34;点&#34;是为了证明我在尽可能少的行中遇到的问题。)
如果您在XCode中将此代码作为macOS控制台应用程序运行,您将看到正在分配内存而不是free
。在仪器中,我可以看到在newClosures.append(closure)
分配内存,这是有道理的。我不明白为什么将closures
分配给newClosures
并不free
旧版newClosures
。相反,分配似乎无限增长,直到我EXC_BAD_ACCESS代码= 2。
值得注意的是,它甚至没有分配太多内存。在我的测试中,应用程序在分配大约17MB后崩溃(它从大约5MB开始,并在大约60s内上升到17MB)。所以我认为这与保留的对象数量有关,而不是它们的纯粹大小。
如果我将带有数组的closures
数组替换为其他引用类型,例如
class Foo { }
var foos: [Foo] = []
foos.append(Foo())
while true {
var newFoos: [Foo] = []
for foo in foos {
newFoos.append(foo)
}
foos = newFoos
}
它按预期工作。我认为必须在闭包每次循环中捕获越来越多的东西时会发生什么?但我不明白这是怎么回事。
我可能会重构代码来解决这个问题,但此时我只是想了解发生了什么。