这是一个非常简单的递归函数:
func lap (n: Int) -> Int {
if n == 0 { return 0 }
return lap (n - 1)
}
Run Code Online (Sandbox Code Playgroud)
如果我想将其转换为闭包:
let lap = {
(n: Int) -> Int in
if n == 0 { return 0 }
return lap (n - 1)
}
Run Code Online (Sandbox Code Playgroud)
我收到一个编译器错误:"变量在其自己的初始值中使用"
Bry*_*hen 11
您可以通过两步分配来解决它
var lap : (Int) -> Int!
lap = {
(n: Int) -> Int in
if n == 0 { return 0 }
return lap(n - 1)
}
Run Code Online (Sandbox Code Playgroud)
func Y<T, R>( f: (T -> R) -> (T -> R) ) -> (T -> R) {
return { t in f(Y(f))(t) }
}
let lap = Y {
(f : Int -> Int) -> (Int -> Int) in
return { (n : Int) -> Int in return n == 0 ? 0 : f(n - 1) }
}
// with type inference
let lap2 = Y {
f in { n in n == 0 ? 0 : f(n - 1) }
}
Run Code Online (Sandbox Code Playgroud)
这是@zneak发现的内存泄漏问题的解决方法 (它没有内存泄漏但是捕获了错误的值)
func f(n: Int) {
var f = Foo()
var lap: @objc_block (Int)->Int = { $0 }
var obj: NSObject = reinterpretCast(lap)
lap = {
[weak obj] (n: Int) -> Int in // unowned will cause crush
if n == 0 { return 0 }
println(f)
var lap2 : @objc_block (Int)->Int = reinterpretCast(obj)
return lap2 (n - 1)
}
lap(n)
}
for i in 0..<5 {
f(i)
}
class Foo {
init() {
println("init");
}
deinit {
println("deinit")
}
}
Run Code Online (Sandbox Code Playgroud)
zne*_*eak 10
编辑这已经使用嵌套函数使用Swift 2解决了.Apple建议使用以下代码:
func f(n: Int) {
func lap(n: Int) -> Int {
if n == 0 { return 0 }
print(n)
return lap(n - 1)
}
lap(n)
}
for i in 0..<1000000 { f(i) }
Run Code Online (Sandbox Code Playgroud)
虽然这在当前示例中并不明显,但所谓的局部函数捕获了封闭范围的局部变量.
使用位置函数不会泄漏,而封闭会发生泄漏.但是,显然,lap在这种情况下无法重新分配.
我收到了Apple的Joe Groff发来的一封电子邮件,声称他们仍然计划在稍后的时间内将闭包捕获为弱变量和可变变量.但这确实证实,除了本地功能之外,现在没有办法做到这一点.
您当前的解决方案中存在内存泄漏:lap封闭具有对自身的强烈引用,这意味着它无法释放.通过附带Leaks仪器启动以下程序可以轻松验证这一点:
import Foundation
func f(n: Int) {
var lap: (Int)->Int = { $0 }
lap = {
(n: Int) -> Int in
if n == 0 { return 0 }
println(n)
return lap (n - 1)
}
lap(n)
}
for i in 0..<1000000 {
f(i)
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,由于显式捕获语法不能应用于闭包类型(你得到的错误说"'无主'不能应用于非类型'(Int) - > Int'"),似乎没有简单的方法实现这一点而不泄漏.我提交了一份关于它的错误报告.
| 归档时间: |
|
| 查看次数: |
2652 次 |
| 最近记录: |