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 1
@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 1
@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 |