mra*_*214 5 key-value-observing ios swift
我是否需要订阅/取消订阅数组的各个元素?
我想单独更新每个表视图单元格以反映支持数组中的更改.通过更改,我的意思是不追加/删除操作,而是更新数组对象的属性.我希望我能够解释我想要实现的目标.谢谢
要使用KVO,请使用dynamic属性声明模型对象:
class Foo: NSObject {
@objc dynamic var bar: String // in Swift 3, `@objc` is not necessary; in Swift 4 we must make this explicit
init(bar: String) {
self.bar = bar
super.init()
}
}
Run Code Online (Sandbox Code Playgroud)
然后,让细胞处理KVO.首先,我有一个协议,通过该协议,单元可以通知表视图需要重新加载:
protocol CustomCellDelegate: class {
func didUpdateObject(for cell: UITableViewCell)
}
Run Code Online (Sandbox Code Playgroud)
并且表视图控制器可以符合此CustomCellDelegate协议,并在获知需要时重新加载单元:
func didUpdateObject(for cell: UITableViewCell) {
if let indexPath = tableView.indexPath(for: cell) {
tableView.reloadRows(at: [indexPath], with: .fade)
}
}
Run Code Online (Sandbox Code Playgroud)
那么,然后定义单元格来设置和处理KVO.在Swift 4和iOS 11中,您可以使用基于闭包的observe方法和新的强类型键:
class CustomCell: UITableViewCell {
weak var delegate: CustomCellDelegate?
private var token: NSKeyValueObservation?
var object: Foo? {
willSet {
token?.invalidate()
}
didSet {
textLabel?.text = object?.bar
token = object?.observe(\.bar) { [weak self] object, change in
if let cell = self {
cell.delegate?.didUpdateObject(for: cell)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在Swift 3中:
class CustomCell: UITableViewCell {
private var observerContext = 0
weak var delegate: CustomCellDelegate?
var object: Foo? {
willSet {
object?.removeObserver(self, forKeyPath: #keyPath(Foo.bar), context: &observerContext)
}
didSet {
textLabel?.text = object?.bar
object?.addObserver(self, forKeyPath: #keyPath(Foo.bar), context: &observerContext)
}
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard context == &observerContext else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
return
}
delegate?.didUpdateObject(for: self)
}
deinit {
object?.removeObserver(self, forKeyPath: #keyPath(Foo.bar), context: &observerContext)
}
}
Run Code Online (Sandbox Code Playgroud)
现在cellForRowAtIndexPath可以设置delegate和object属性:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
cell.delegate = self
cell.object = objects![indexPath.row]
return cell
}
Run Code Online (Sandbox Code Playgroud)
在我看来,这个KVO机制比Swift观察器机制更好,因为模型对象不需要知道(也不应该)关于观察者的任何事情.它只需要表明它支持动态调度,就是这样.
对于上面的Swift 2演绎,请参阅此答案的先前修订版.
| 归档时间: |
|
| 查看次数: |
7937 次 |
| 最近记录: |