我使用的是Xcode6-beta2,但自从第一个公开测试版以来,我遇到了同样的问题。 Obj-C UIViewController的My Swift子类如下所示:
class SomeVC: UIViewController {
var c1: () -> () = {
println(self)
}
var c2: () -> () {
get {
return { println(self) }
}
}
var c3: () -> () {
return { println(self) }
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
c1()
c2()
c3()
}
}
当显示VC时,我看到打印出以下行:
(Function)
<_TtC12SwiftiOSTest6SomeVC: 0x10bf1ed10>
<_TtC12SwiftiOSTest6SomeVC: 0x10bf1ed10>
(c2和c3的不同之处仅在于,如果计算属性只能获取,则不必包含get {...}。)
所以,第一个闭包的 self 似乎是指函数/闭包类型本身,而其他的那些&#39; self 指的是视图控制器(正如我所料)。 c1和c2 / c3之间的唯一区别是前者是存储属性,后者是计算属性,但我仍然希望闭包及其捕获值相同,即 self 总是请参阅附上的课程。现在的方式,似乎没有明显的方法让 c1 闭包来访问封闭类的方法/属性。
这是在某处记录的(我阅读了Swift书并没有找到任何东西),或者它只是某种类型的beta编译器错误,应该在某处提交?
答案 0 :(得分:58)
这看起来很有趣。所以我做了调查。您可以在闭包内访问类实例变量,如self.instanceVariable
。那时关闭将 捕获 其中的self
。所以现在self
引用了类实例本身。你的闭包应该是 lazy 属性。
惰性属性意味着你可以在默认闭包中引用self,因为在初始化完成并且已知self存在之后才会访问lazy属性。
您缺少 @lazy ,因此关闭时未知self
这就是为什么它打印为(Function)
我的猜测。< / p>
class TableViewController: UIViewController {
var name = "anil"
// Since swift 2.0 came out @lazy is replaced by lazy
lazy var c1: () -> () = {
println(self)
println(self.name)
}
var c2: () -> () {
get {
return { println(self) }
}
}
var c3: () -> () {
return { println(self) }
}
override func viewDidLoad() {
super.viewDidLoad()
c1()
c2()
c3()
}
}
输出
&lt; _TtC12TableViewApp19TableViewController:0x10d54e000&gt;
阿尼尔
&lt; _TtC12TableViewApp19TableViewController:0x10d54e000&gt; &lt; _TtC12TableViewApp19TableViewController:0x10d54e000&gt;
更新
为类实例变量分配闭包会产生强引用周期。你应该避免这种情况。 Swift使用捕获列表来实现
如果为类实例的属性分配闭包,并且闭包通过引用实例或其成员来捕获该实例,则将在闭包和实例之间创建一个强引用循环。 Swift使用捕获列表来打破这些强大的参考周期。有关详细信息,请参阅Strong Reference Cycles for Closures。
所以关闭的正确用法可能是
@lazy var c1: () -> () = {
[unowned self] in
println(self)
println(self.name)
}
修改强>
@lazy 已更改为懒惰