从正在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已经变成懒惰了