NSKeyValueObservation observe() 闭包中是否需要弱自我?
Is weak self needed in NSKeyValueObservation observe() closure?
我有:
private var statusLabel: UILabel!
private var errorObserver: NSKeyValueObservation?
self.errorObserver = self.viewModel.observe(\.errorString)
{ [weak self] (viewModel, change) in
self?.statusLabel.text = viewModel.errorString
}
这里需要[weak self]
吗?
简短回答:是的,您确实需要 [weak self]
。不必在 deinit
中明确删除观察者是一个很好的便利,它确保观察中心不会向 de-initialized 观察者发送通知,但并不免除您必须为关闭管理内存。
Apple 的官方文档(Swift 编程语言 4.0.3)指出:
By default, a closure expression captures constants and variables from its surrounding scope with strong references to those values. You can use a capture list to explicitly control how values are captured in a closure.
A capture list is written as a comma-separated list of expressions surrounded by square brackets, before the list of parameters. If you use a capture list, you must also use the in keyword, even if you omit the parameter names, parameter types, and return type.
....
If the type of the expression’s value is a class, you can mark the expression in a capture list with weak or unowned to capture a weak or unowned reference to the expression’s value.
Excerpt From: Apple Inc. “The Swift Programming Language (Swift 4.0.3).” iBooks.
如果在捕获列表中不标记表达式self
,将创建一个强引用循环。因为classes是引用类型,而闭包是引用类型,所以产生了强引用循环。当闭包的主体引用 class 的实例时,闭包会创建对 class 实例的引用。默认情况下,这是一个强引用,除非您使用捕获列表来定义不同类型的引用。官方注释连 say:
Swift requires you to write self.someProperty
or self.someMethod()
(rather than just someProperty
or someMethod()
) whenever you refer to a member of self
within a closure. This helps you remember that it’s possible to capture self
by accident.
在您的例子中,您引用的是闭包体内的标签。你需要写的事实
self?.statusLabel.text = viewModel.errorString
而不是简单地
.statusLabel.text = viewModel.errorString
提示您在捕获列表中使用 self
。
我有:
private var statusLabel: UILabel!
private var errorObserver: NSKeyValueObservation?
self.errorObserver = self.viewModel.observe(\.errorString)
{ [weak self] (viewModel, change) in
self?.statusLabel.text = viewModel.errorString
}
这里需要[weak self]
吗?
简短回答:是的,您确实需要 [weak self]
。不必在 deinit
中明确删除观察者是一个很好的便利,它确保观察中心不会向 de-initialized 观察者发送通知,但并不免除您必须为关闭管理内存。
Apple 的官方文档(Swift 编程语言 4.0.3)指出:
By default, a closure expression captures constants and variables from its surrounding scope with strong references to those values. You can use a capture list to explicitly control how values are captured in a closure.
A capture list is written as a comma-separated list of expressions surrounded by square brackets, before the list of parameters. If you use a capture list, you must also use the in keyword, even if you omit the parameter names, parameter types, and return type.
....
If the type of the expression’s value is a class, you can mark the expression in a capture list with weak or unowned to capture a weak or unowned reference to the expression’s value.
Excerpt From: Apple Inc. “The Swift Programming Language (Swift 4.0.3).” iBooks.
如果在捕获列表中不标记表达式self
,将创建一个强引用循环。因为classes是引用类型,而闭包是引用类型,所以产生了强引用循环。当闭包的主体引用 class 的实例时,闭包会创建对 class 实例的引用。默认情况下,这是一个强引用,除非您使用捕获列表来定义不同类型的引用。官方注释连 say:
Swift requires you to write
self.someProperty
orself.someMethod()
(rather than justsomeProperty
orsomeMethod()
) whenever you refer to a member ofself
within a closure. This helps you remember that it’s possible to captureself
by accident.
在您的例子中,您引用的是闭包体内的标签。你需要写的事实
self?.statusLabel.text = viewModel.errorString
而不是简单地
.statusLabel.text = viewModel.errorString
提示您在捕获列表中使用 self
。