天天看點

iOS KVC和KVO的使用

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")
            }
        }
    }