
class Person { func goHome() { println("test") } deinit { println("Persion deinit") } } class Apartment { var somebodyCome: (() -> ())? deinit { println("Apartment deinit") } } var person: Person? = Person() var apartment: Apartment? = Apartment() apartment!.somebodyCome = person!.goHome person = nil // Output: [nothing] Apartment 引用了一个 Person的方法 goHome() 作为 somebodyCome 时的动作。
但是这会造成强引用。 不过无法写这样的语句 weak var somebodyCome: (() -> ())? 。
这种情况下的最佳实践应该是什么?
1 jakwings 2014-11-19 00:52:56 +08:00 为什么不引用Person而是引用函数?反正对象销毁的时候你也不需要那个函数了吧,而当函数还有用的时候对象也依然存在着。 |
3 WildCat OP @jakwings 没有吧,我这里的实际需求是,一个 Custom View 的发生变化的时候(类似 TabView 左滑动到上一页),通知Controller. 一般的做法是用 delegate + protocol ,这里我想直接用 Closure 。 但是我在 Controller 里打算用一个函数而不是闭包。主要是增加易读性。 没有增加耦合吧 |
4 jakwings 2014-11-19 12:52:00 +08:00 @WildCat apartment直接调用了person的method,而不是让person去调用,明显是越权了。而且强弱引用只能应用到class上面,你也没有什么别的办法了。在调用的时候,虽然函数使用的self依然是指向person,但是总感觉怪怪的,不知道self能否保证永远指向person,官方教程上貌似没有说到。 |
5 WildCat OP @jakwings https://github.com/HeshamMegid/HMSegmentedControl/blob/master/HMSegmentedControlExample/HMSegmentedControlExample/ViewController.m 63~68 行: 既然在 Swift 中函数也是一等公民,我想把 indexChangeBlock 设置为 ViewController 的实例方法. 这样不合法吗? |
6 jakwings 2014-11-19 19:13:03 +08:00 @WildCat method虽然也是函数,可它是属于对象/实例的,你可以让一个固定的method对self进行unowned吗?假如不行的话,就和相应对象/实例脱不了身了。可以考虑把那个method用closure替代,在初始化时添加好,不绑死在对象上。 |
7 jakwings 2014-11-19 19:42:40 +08:00 |
8 jakwings 2014-11-19 19:47:41 +08:00 @jakwings 看来不故意设置变量为nil的话deinit里的输出是会被抛弃的,不知道这算不算是bug,或者说程序是在释放了println函数之后才开始对象的销毁操作…… |
10 jakwings 2014-11-21 01:32:16 +08:00 @WildCat 那用xcrun swift test.swift执行呢?我这样做同样在程序结束时没有deinit的输出,在程序结束前自行设为nil就有。我觉得好像和全局对象无关吧?我在SO那里问了: https://stackoverflow.com/questions/27044573/swift-no-output-for-println-in-deinit-method |