【问题标题】:object communication when object is not kvc compliant in Swift对象在 Swift 中不符合 kvc 时的对象通信
【发布时间】:2018-02-13 16:17:42
【问题描述】:

我想创建一个自定义视图,当另一个对象(UIControl 的子类)上发生操作(如更改属性)时显示它

我的方法就是这样

  1. 创建一个 UIControl 对象可以遵循的协议
  2. 创建我可以观察我的委托的自定义视图

不幸的是,它不起作用,更糟糕的是,它崩溃了,因为编译器说“它不符合 kvc”

贝娄,我的代码:

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

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

【问题讨论】:

    标签: ios swift protocols key-value-observing cocoa-design-patterns


    【解决方案1】:

    你addObserver错了,“observer”应该是self没有“keypath”

    试试这个:

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

    【讨论】:

      【解决方案2】:

      您没有正确阅读您的错误。例如:

      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.. 不要忘记稍后删除观察者。

      【讨论】:

      • 非常感谢您花时间理解和解决我的问题! +1
      猜你喜欢
      • 2012-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多