当对象不符合kVC时,对象通信在swift中



我想创建一个自定义视图,该自定义视图在另一个对象上发生操作(如更改的属性(( uicontrol的子类(

>

我的方法是

  1. 创建一个协议,其uicontrol对象可以符合
  2. 创建我的自定义视图,我可以观察我的委托

不幸的是,这是行不通的,更糟糕的是,这是崩溃的,因为编译器说"它不符合KVC符合KVC"

Bellow,我的代码:

protocol CustomDelegate: class where Self : UIControl {
    func respondeToControl() -> Bool
}
class CustomView: UIView {
    weak var delegate: CustomDelegate? {
        didSet{
             observeIfControlIsPressed()
       }
   }
   func observeIfControlIsPressed(){
       if delegate != nil {
            let keypath = delegate! as! UIControl
            keypath.addObserver(keypath,
                            forKeyPath: "backgroundColor",
                         options: [NSKeyValueObservingOptions.new, NSKeyValueObservingOptions.old],
            context: nil)
        }
   }
   open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
       print("background changed")
   }
}

我的问题是,我如何重新设计解决方案以实现它工作?

您是错误的,"观察者"应该是 self no" keypath"

尝试以下操作:

keypath.addObserver(self, forKeyPath: "backgroundColor", options: [.new, .old], context: nil)

您未正确读取错误..例如:

protocol CustomDelegate : class where Self : UIControl {
    func respondeToControl() -> Bool
}
class CustomView: UIView {
    weak var delegate: CustomDelegate? {
        didSet{
            observeIfControlIsPressed()
        }
    }
    func observeIfControlIsPressed(){
        if delegate != nil {
            let keypath = delegate! as! UIControl
            keypath.addObserver(keypath,
                                forKeyPath: "backgroundColor",
                                options: [NSKeyValueObservingOptions.new, NSKeyValueObservingOptions.old],
                                context: nil)
        }
    }
    open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        print("background changed")
    }
}
class Foo : UIControl, CustomDelegate {
    func respondeToControl() -> Bool {
        return true
    }
}

class ViewController: UIViewController {
    let testBlock = UIView()
    override func viewDidLoad() {
        super.viewDidLoad()
        let view = CustomView()
        let button = Foo()
        view.delegate = button
        button.backgroundColor = UIColor.red
    }
}

抛出异常:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '<Meh.Foo: 0x7fc977c1a0c0; baseClass = UIControl; frame = (0 0; 0 0); layer = <CALayer: 0x608000226480>>: An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: backgroundColor

这意味着Foo正在观察foo,但未实现observeValueForKeyPath功能。

现在为什么?好..这是因为您做到了:

keypath.addObserver(keypath,  //keypath is observing itself..
                    forKeyPath: "backgroundColor",
                    options: [NSKeyValueObservingOptions.new, NSKeyValueObservingOptions.old],
                    context: nil)

其中 keypath是您的代表。

应该是:

keypath.addObserver(self,  //self is observing keypath..
                        forKeyPath: "backgroundColor",
                        options: [NSKeyValueObservingOptions.new, NSKeyValueObservingOptions.old],
                        context: nil)

addObserver的第一个参数需要是要进行观察的类。

更改将导致其打印:background changed ..不要忘记以后删除观察者。

最新更新