本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 —— 4.在 Combine 中使用 KVO

 

内容概览

  • 前言
  • KVO 监控改动
  • KVO 代码迁移到 Combine
  • 总结

 

前言

 

KVO([Key-Value Observing](Using Key-Value Observing in Swift)) 是苹果开发者常用的功能,很多框架都会使用 KVO 来发送异步改动。将基于回调和闭包的 KVO 代码迁移到 Combine,可以使你的代码更优雅、更易维护。

 

用 KVO 监控改动

 

在下面的示例中, UserInfo 类型为它的 lastLogin 属性提供了 KVO 支持。示例代码在 viewDidLoad() 方法中调用了 observe(_:options:changeHandler:) 方法来创建了一个处理这个属性的变动的闭包。这个闭包接收一个描述了改动事件的 NSKeyValueObservedChange 对象,并从这个对象取出了 newValue 属性的值,然后打印。

接下来,示例代码在 viewDidAppear(_:) 方法中改了 lastLogin 属性的值,最终触发了闭包并打印了消息。

class UserInfo: NSObject {
@objc dynamic var lastLogin: Date = Date(timeIntervalSince1970: 0)
} @objc var userInfo = UserInfo()
var observation: NSKeyValueObservation? override func viewDidLoad() {
super.viewDidLoad()
observation = observe(\.userInfo.lastLogin, options: [.new]) { object, change in
print ("lastLogin now \(change.newValue!).")
}
} override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
userInfo.lastLogin = Date()
}

 

将 KVO 代码迁移到 Combine

 

想要迁移 KVO 代码到 Combine,只需替换 observe(_:options:changeHandler:) 方法为 NSObject.KeyValueObservingPublisher。您可以通过在父对象(parent object)上调用 publisher(for:) 方法来获得此发布者的实例,如以下示例的 viewDidLoad() 方法所示:

class UserInfo: NSObject {
@objc dynamic var lastLogin: Date = Date(timeIntervalSince1970: 0)
} @objc var userInfo = UserInfo()
var cancellable: Cancellable? override func viewDidLoad() {
super.viewDidLoad()
cancellable = userInfo.publisher(for: \.lastLogin)
.sink() { date in print ("lastLogin now \(date).") }
} override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
userInfo.lastLogin = Date()
}

KVO发布者 会生成观察类型的元素(在本例中为 Date),而不是 NSKeyValueObservedChange。这样就节省了一步操作,因为你不必像前一个示例中那样从 change 对象中获取 newValue

 

总结

 

如果上面的示例变得更加复杂,传统的 KVO 代码可能会变得非常臃肿,而基于 CombineKVO 代码可以利用各种操作符进行链式调用。这样,就可以让代码更优雅,同时保持代码的易读性。对于以后维护这段代码的人来说,这将是一种辛福的感觉~

朋友,行动起来吧!把现有项目中的旧代码重构成使用 Combine 的代码~

 

本文内容来源:

Performing Key-Value Observing with Combine

 

随机推荐

  1. webstrom配置sass与less

    1.less 安装一个稳定版的node.[例如node-v4.4.4-x64] 然后直接在webstrom里导入那个lessc.cmd 2.sass 安装ruby. 安装完之后点开,Start那个安装 ...

  2. [转]js来弹出窗口的详细说明

    1.警告对话框 <script> alert("警告文字") </script> 2.确认对话框 <script> confirm(" ...

  3. 项目管理知识框架PMBOK(文字版)

    项目管理知识框架PMBOK   项目整体管理[I](Integration) 1. 制定项目章程(Develop Project Charter) 2. 制定项目初步范围说明书(Develop Pre ...

  4. PHP框架学习错误总结

    错误一: Fatal error: “Uncaught exception 'Zend_Controller_Response_Exception' with message 'Cannot send ...

  5. Oracle的GUID:Raw(16)

    最近用了Oracle作为开发的数据库.以前用Sqlserver的时候用GUID作为主键的(数据类型:uniqueidentifier),Oracle的GUID类型变成RAW(16)了.从数据库读出来R ...

  6. Android的ADB工具使用

    在SDK的Tools文件夹下包含着Android模拟器操作的重要命令ADB,ADB的全称为Android Debug Bridge,就是调试桥的作用,借助这个工具,我们可以管理设备或手机模拟器的状态  ...

  7. ESMOD北京高级时装艺术学校_百度百科

    ESMOD北京高级时装艺术学校_百度百科 ESMOD北京高级时装艺术学校

  8. python爬虫(1)——urllib包

    人生苦短,我用python! 一.关于爬虫 鉴于我的windos环境使用命令行感觉非常不便,也懒得折腾虚拟机,于是我选择了一个折中的办法--Cmder.它的下载地址是:cmder.net Cmder是 ...

  9. 微信小程序获取用户手机号

    获取微信用户绑定的手机号,需先调用wx.login接口. 小程序获取code. 后台得到session_key,openid. 组件触发getPhoneNumber 因为需要用户主动触发才能发起获取手 ...

  10. Linux下批量修改文件及文件夹所有者及权限

    Linux下批量修改文件及文件夹所有者及权限需要使用到两个命令,chmod以及chown 例:对/opt/Oracle/目录下的所有文件与子目录执行相同的权限变更: chmod -R 700 /opt ...