【问题标题】:how to override func observeValueForKeyPath on Swift 5.2- Xcode Version 11.5如何在 Swift 5.2-Xcode 版本 11.5 上覆盖 func observeValueForKeyPath
【发布时间】:2020-07-10 16:24:28
【问题描述】:

我正在尝试在 Swift 5.2 - Xcode 版本 11.5 上移植 this interactive playground,但我仍然得到 Method does not override any method from its superclass,但我还没有弄清楚如何设置这个方法签名。我正在学习的课程从UIKit 扩展UIView

我用 Cmd+Shift+O 看了标题NSKeyValueObserving.h,发现:

- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context;

从现在开始我尝试了但没有成功:

    public override func observeValueForKeyPath(keyPath: String!, 
    ofObject object: AnyObject!, 
    change: [String : AnyObject]!, 
    context: UnsafeMutablePointer<()>)
    
    public override func observeValueForKeyPath(keyPath: String!, 
    ofObject object: AnyObject!, 
    change: [String : AnyObject]!, 
    context: UnsafeMutableRawPointer)
    
    public override func observeValueForKeyPath(keyPath: String!, 
    of object: Any?, 
    change: [NSKeyValueChangeKey : Any]?, 
    context: UnsafeMutableRawPointer?)

关于我正在学习的课程的更多信息

import UIKit
import XCPlayground

public class NewtonsCradle: UIView  {
    
    private let colors: [UIColor]
    private var balls: [UIView] = []
    
    private var animator: UIDynamicAnimator?
    private var ballsToAttachmentBehaviors: [UIView:UIAttachmentBehavior] = [:]
    private var snapBehavior: UISnapBehavior?
    
    public let collisionBehavior: UICollisionBehavior
    public let gravityBehavior: UIGravityBehavior
    public let itemBehavior: UIDynamicItemBehavior
    
    public init(colors: [UIColor]) {
        self.colors = colors
        collisionBehavior = UICollisionBehavior(items: [])
        gravityBehavior = UIGravityBehavior(items: [])
        itemBehavior = UIDynamicItemBehavior(items: [])
    
        super.init(frame: CGRect(x: 0, y: 0, width: 480, height: 320))
        backgroundColor = UIColor.white
        animator = UIDynamicAnimator(referenceView: self)
        animator?.addBehavior(collisionBehavior)
        animator?.addBehavior(gravityBehavior)
        animator?.addBehavior(itemBehavior)
        
        createBallViews()
    }
    
    public required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        for ball in balls {
            ball.removeObserver(self, forKeyPath: "center")
        }
    }

   /* SNIP */

   public override func observeValueForKeyPath(keyPath: String!, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if (keyPath == "center") {
            setNeedsDisplay()
        }
    }
  /* SNIP */

【问题讨论】:

  • 你实现了super吗?或者,如果找不到该方法,您可以扩展。
  • 我将编辑问题以提供有关初始化代码的详细信息
  • @TwisteDx 这能回答你的问题吗?您可以尝试制定答案,以便我尝试可能的解决方案吗?
  • 啊,让你的 keyPath:字符串!变成一个可选的。
  • 我将您的代码复制粘贴到操场上并开始输入“observe”,xcode autocomplete 建议使用此方法:public override func observeValue(forKeyPath keyPath: String?, of object: Any?,更改:[NSKeyValueChangeKey:Any]?,上下文:UnsafeMutableRawPointer?){}。这是你要找的吗?

标签: swift swift5 xcode11 swift-playground key-value-observing


【解决方案1】:

您的覆盖应该如下所示。它要求您的参数是可选的。

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    // Do your work here.
}

每当发生这种情况时,请查看CMD+SHFT+O 对该方法的定义,以查看定义并验证您的参数是否与预期相符。我相信这是一个比您的用例更新的 Swift 版本,但它仍然应该适用。

【讨论】:

    猜你喜欢
    • 2015-06-29
    • 1970-01-01
    • 1970-01-01
    • 2015-09-27
    • 2020-05-02
    • 2012-05-14
    • 2016-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多