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 {…}。)
所以,第一个闭包的自我似乎指向函数/闭包类型本身,而其他的自我指的是视图控制器(如我所料)。
c1和c2 / c3之间的唯一区别是前者是一个存储属性,后者是计算属性,但我仍然期望闭包和它们捕获的值是相同的,即self总是引用封闭类。现在的方式,似乎没有明显的方法为c1闭包访问方法/属性的封闭类。
这是记录在某处的东西(我读了Swift的书,没有找到任何东西),还是它只是一种beta编译器错误,应该提交某处?
A lazy property means that you can refer to self within the default closure,because the lazy property will not be accessed until after initialization has been completed and self is kNown to exist.
你缺少@lazy所以自我是未知的闭包,这就是为什么它打印为(函数)我的猜测。
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>
anil
<_TtC12TableViewApp19TableViewController: 0x10d54e000>
<_TtC12TableViewApp19TableViewController: 0x10d54e000>
更新
将闭包分配给类实例变量会产生很强的参考周期。你应该避免这个。 Swift使用Capture列表
If you assign a closure to a property of a class instance,and the closure captures that instance by referring to the instance or its members,you will create a strong reference cycle between the closure and the instance. Swift uses capture lists to break these strong reference cycles. For more information,see 07000.
所以正确使用闭包可以
@lazy var c1: () -> () = { [uNowned self] in println(self) println(self.name) }
编辑@lazy已改为延迟