一、KVO
kvo键值观察者
Swift继承NSObject的KVO
swift
实现kvo
需要两个条件,第一要是NSObject
的子类,第二要在观察的属性添加@objc dynamic
class Animal: NSObject {
@objc dynamic var name: String = "ob";
}
class ViewController: UIViewController {
let dog = Animal.init();
var observation: NSKeyValueObservation?
override func viewDidLoad() {
super.viewDidLoad()
observation = dog.observe(\Animal.name, options: [.new,.old]) { (Animal, change) in
if let name = change.oldValue {
print("old:" + name)
}
if let name = change.newValue {
print("new:" + name)
}
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
dog.name = "i_am_Tom";
}
}
打印
old:ob
new:i_am_Tom
Swift中set方法
有set和get方法
class Animal {
var _name:String = "";
var name:String {
set {
_name = newValue;
}
get {
return _name;
}
};
}
如果没有get方法
class Animal {
var _name:String = "";
var name:String = "ob" {
set {
_name = newValue;
}
};
}
注意:
一旦实现了willSet
和didSet
方法,就不能实现set和get
方法,set\get
与willset
只能存在一种
class Animal {
var _name:String = "";
var name:String = "ob" {
willSet {
// code ...
}
didSet {
}
};
}
Swift非NSObject实现KVO
主要是利用set
方法中的willSet
和didSet
特性;
public class OBKVO<Type> {
private var callback:((_ oldValue:Type, _ newValue:Type) ->())?;
init(_ value: Type) {
self.value = value;
}
var value: Type {
didSet {
self.callback!(oldValue,value);
}
}
func addObserver(_ callback:@escaping (_ oldValue: Type, _ newValue:Type) ->()) {
self.callback = callback;
}
}
class Person {
var name: OBKVO<String>;
init(name :String ) {
self.name = OBKVO.init(name);
}
}
调用
class ViewController: UIViewController {
let person = Person.init(name: "obnb");
override func viewDidLoad() {
super.viewDidLoad()
person.name.addObserver { (old, new) in
print("old is \(old),-- new vlaue is \(new)");
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
person.name.value = "i_am_Mack";
}
}
打印结果:
old is obnb,-- new vlaue is i_am_Mack