Swift4

来源:互联网 发布:手机淘宝评价删除不了 编辑:程序博客网 时间:2024/05/17 10:40

KVC和KVO是我们开发中常用的功能,现在来看一下在Swift4中的变化

KVC

在Swift4的时候,Struct也支持KVC,我们不在使用setValue: forKeypath的方式,而是使用新的语法特性,下面看一下例子,参考这里:

struct Person {    var name: String}struct Book {    var title: String    var authors: [Person]    var primaryAuthor: Person {        return authors.first!    }}let abelson = Person(name: "Haeold Abelson")let sussman = Person(name: "Garald Jay Sussman")var book = Book(title: "tructure and Interpretation of Computer Programs", authors: [abelson, sussman])//get//1 keyPath以\开始,然后开始组合结构体和属性let title = book[keyPath: \Book.title]print(title) //tructure and Interpretation of Computer Programs//2 keypath可以进入多层深入搜索查找,也可以对计算属性进行操作let name = book[keyPath: \Book.primaryAuthor.name]print(name) //Haeold Abelson//setbook[keyPath: \Book.title] = "KVC"print(book[keyPath: \Book.title]) // KVC

对象的路径操作

//先获取一个路径let authorKeyPath = \Book.primaryAuthor//拼接子路径let nameKeyPath = authorKeyPath.appending(path: \.name)let newName = book[keyPath: nameKeyPath]print(newName) //Haeold Abelson

KVO

@objcMembers class Food: NSObject {    dynamic var string: String    override init() {        string = "hotdog"        super.init()    }}let food = Food()let observation = food.observe(\.string) { (foo, changed) in     print("new food string: \(foo.string)")}food.string = "not hotdog" // new food string: not hotdog
上面代码很简单,创建了一个Food类,拥有一个string属性,但是需要注意几件事情:

1)用KVO依然需要是NSObject类或子类,Swift4中swift类不再自动被推测为继承于NSObject,所以当我们在编写swift的代码时,需要为类添加@objcMembers关键字

2)注意到属性string,我们使用了dynamic关键字,主要是告诉观察者在值发生改变之后触发闭包,如果没有该关键字,那么无法观察到值的改变

3)使用新语法特性\.string监听属性变化

4)最开心的事就是我们不在需要手动去除观察者,以前都需要在deinit()中去除观察者


当然,我们也可以为属性添加@objc,那么类就不在需要@objcMembers关键

class Child: NSObject {    let name: String    // KVO-enabled properties must be @objc dynamic    @objc dynamic var age: Int    init(name: String, age: Int) {        self.name = name        self.age = age        super.init()    }    func celebrateBirthday() {        age += 1    }}
使用方法是一样,接下来使用带有options参数的方法:

//Set up KVOlet mia = Child(name: "Mia", age: 5)let observation = mia.observe(\.age, options: [.initial, .old]) { (child, change) in    if let oldValue = change.oldValue {        print("\(child.name)’s age changed from \(oldValue) to \(child.age)")        //Mia’s age changed from 5 to 6    } else {        print("\(child.name)’s age is now \(child.age)")        //Mia’s age is now 5      }    }//Trigger KVO (see output in the console)mia.celebrateBirthday()//Deiniting or invalidating the observation token ends the observationobservation.invalidate()//This doesn't trigger the KVO handler anymoremia.celebrateBirthday()

options参数,我们设置了两个值,.initial,.old,表示获取最开始的值,和变化前的值。KVO的options一共有4种:

public struct NSKeyValueObservingOptions : OptionSet {    public init(rawValue: UInt)    public static var new: NSKeyValueObservingOptions { get } //变化前的值    public static var old: NSKeyValueObservingOptions { get } //变化后的值    public static var initial: NSKeyValueObservingOptions { get } // 初始值    public static var prior: NSKeyValueObservingOptions { get } // notification变化前後的标准}


监听WebKit加载进度

class ViewController: UIViewController {    var webView: WKWebView!    var urlPath: String = "https://www.baidu.com/"    var progressView: UIProgressView!    var observer: NSKeyValueObservation!     override func viewDidLoad() {        super.viewDidLoad()          setupWebView()    }    func setupWebView() {        webView = WKWebView(frame: view.frame)        view.addSubview(webView)        progressView = UIProgressView(frame: CGRect(x: 0, y: 43, width: view.bounds.width, height: 1.0))        navigationController?.navigationBar.addSubview(progressView)        observer = webView.observe(\.estimatedProgress, options: .new) { [weak self] (_, changed) in            if let new = changed.newValue {                self?.changeProgress(Float(new))            }        }        if let url = URL(string: urlPath) { webView.load(URLRequest(url: url)) }    }    func changeProgress(_ progress: Float) {        progressView.isHidden = progress == 1        progressView.setProgress(progress, animated: true)    }}



参考:

Key Value Observation in iOS 11

Smart KeyPaths: Better Key-Value Coding for Swift

What's new in swift4




原创粉丝点击