KVC:使用字元串來描述對象需要更改的屬性,用來擷取或修改對象的屬性值。
[Student setValue:@"1234" forKeyPath: @"card.no"];
[Student valueForKeyPath:@"card.no"]
KVO是一種非常重要的機制,用來監聽對象屬性的變化。
//1.添加觀察者
[stu addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
//2.實作監聽方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if([keyPath isEqualToString:@"frame"]) {
NSLog(@"keyPath=%@,object=%@,newValue=%.2f,context=%@",keyPath,object,[[change objectForKey:@"new"] floatValue],context);
}
}
//3.移除監聽器
[stu removeObserver:self forKeyPath:@"frame"];
然後用Swift舉個例子:監聽目前控制器frame的變化修改按鈕的frame
init() {
super.init(frame: CGRect.init(x: 0, y: ScreenHeight - 49, width: ScreenWidth, height: 49))
self.addSubview(plusButton)
//KVC指派
plusButton .setValue(CGPoint.init(x: ScreenWidth / 2, y: 49 - plusButton.bounds.size.height / 2), forKey: "center")
//添加KVO
self .addObserver(self, forKeyPath: "frame", options: .new, context: nil)
}
convenience init(delegate: LAXTabBarDelegate) {
self.init()
self.tabbarDelegate = delegate
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
//移除KVO
removeObserver(self, forKeyPath: "frame")
}
//實作KVO
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "frame" {
if let rect = change?[.newKey] as? CGRect {
plusButton .setValue(CGPoint.init(x: rect.size.width / 2, y: 49 - plusButton.bounds.size.height / 2), forKey: "center")
}
}
}