从正在closures的实例属性中访问自己

我使用的是Xcode6-beta2,但自从第一次公开testing以来,我遇到了同样的问题。 我的Obj-C UIViewController的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的不同之处在于,如果只有gettable,则不需要包含get {…}。

所以,第一个闭包的自我似乎是指的是函数/闭包types本身,而其他的引用视图控制器(正如我所期望的)。 c1和c2 / c3之间的唯一区别是前者是一个存储属性,后者是计算属性,但我仍然期望封闭和它们的捕获值是相同的,即自我总是引用封闭类。 现在的情况是,似乎没有明显的方式让c1闭包访问封闭类的方法/属性。

这是什么东西logging在某处(我读了Swift书,没有find任何东西),还是只是一个beta编译器的错误,应该提交某处?

这看起来很有趣。 所以我做了一个调查。 您可以像封闭self.instanceVariable一样self.instanceVariable闭包内的类实例variables。 那时closures会抓住它内部的self 。 所以现在self指的是类实例本身。 你的closures应该是一个懒惰的属性。

一个懒惰的属性意味着你可以在默认的闭包中引用self,因为在初始化完成并且已知self存在之前,lazy属性将不被访问。

你错过了@lazy所以封闭self是未知的为什么它打印它(Function)我的猜测。

 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() } } 

产量

<_TtC12TableViewApp19TableViewController:0x10d54e000>
阿尼尔
<_TtC12TableViewApp19TableViewController:0x10d54e000> <_TtC12TableViewApp19TableViewController:0x10d54e000>


更新

将闭包分配给类实例variables会导致强参考周期。 你应该避免这一点。 Swift使用Capture列表

如果将闭包分配给类实例的属性,并且闭包通过引用实例或其成员来捕获该实例,则将在闭包和实例之间创build一个强引用循环。 Swift使用捕获列表来打破这些强大的参考周期。 有关更多信息,请参见强closures循环的闭包 。

所以closures的正确用法可能是

 @lazy var c1: () -> () = { [unowned self] in println(self) println(self.name) } 

参考: Swift编程指南

编辑
@ lazy已经变成懒惰了