【问题标题】:Overriding properties in swift快速覆盖属性
【发布时间】:2015-02-28 20:36:10
【问题描述】:

例如有一个头等舱

public class MyBaseButton: UIButton {

    public var weight: Double = 1.0

    public var text: String? {
        get {
            return self.titleForState(.Normal)
        }
        set {
            return self.setTitle(newValue, forState: .Normal)
        }
    }
}

以及继承类:

public class SomeButton: SomeBaseButton {

    override public var text: String? = "text"
    override public var weight: Double = 2.0
}

所以,逻辑是SomeClass 定义自己的文本和权重。 但我收到了一个错误:

对于文本:“不能用存储的属性'text'覆盖

对于重量:“不能用存储的属性‘重量’覆盖

【问题讨论】:

标签: ios swift properties


【解决方案1】:

有趣的是,这在纯 Swift 类中工作得很好。例如,这按预期工作:

public class FooButton {
    public var weight: Double = 1.0
}

public class BarButton: FooButton {
    override public var weight: Double = 2.0
}

它不适合你的原因是因为你正在使用 Objective-C 类:因为UIButton 是一个 Objective-C 类,它的所有子类也是。因此,规则似乎有点不同。

Xcode 6.3 实际上提供了更多信息。它显示以下两个错误:

“权重”的 Getter 覆盖了来自超类“FooButton”的 Objective-C 方法“权重” “权重”的设置器覆盖来自超类“Foobutton”的Objective-C方法“setWeight:”

由于以下确实有效...

public class BarButton: FooButton {
    override public var weight: Double {
        get {
            return 2.0
        }
        set {
            // Do Nothing
        }
    }
}

...我的猜测是这些方法根本没有正确合成。

我想知道这是否是编译器错误。或者是缺点。因为我认为它可以处理这个案子。

也许 Swift 设计者认为,在覆盖 weight 的情况下,您也可以在初始化程序中简单地将其设置为不同的值。嗯。

【讨论】:

  • 对我来说,你的第一个例子没有编译。不适用于 Xcode 6.3.2 (Swift 1.2) 和 Xcode 7.0 beta (Swift 2.0)。只是抛出编译器错误:“不能用存储的属性权重覆盖”
  • 更简单:override public var weight: Double { return 2.0 }
  • @ixany 在 Swift 4 中为我添加到基本视图控制器的 CUSTOM 属性绝对有用。
【解决方案2】:

另外,如果有人想要覆盖属性以产生dynamic 效果,请参阅KVO

class MyClass: NSObject {
    var date = NSDate()
}

class MyChildClass: MyClass {
    dynamic override var date: NSDate {
        get { return super.date }
        set { super.date = newValue }
    }
}

【讨论】:

    【解决方案3】:

    在上面你有一个 getter 和一个 setter。

    当你覆盖它时,你只是给它一个值。

    而是像上面那样设置 setter 和 getter。

    var _text:Text
    
       override public var text: String? {
                get {
                    return _text
                }
                set {
                    _text = newValue
                }
            }
    

    【讨论】:

    • 但我只需要“文本”作为默认值。在您的示例中,无法更改文本属性
    • 好的,那么你只需将 newValue 分配给它
    • 添加一个私有成员变量并使用它来存储数据。你需要把它放在super中。
    • 你没有错过override关键字吗?
    【解决方案4】:

    我在尝试覆盖 Swift 3 中的 NSPredicateRowEditor templateViews 属性时遇到了这个问题。

    要覆盖的超类属性:

    open var templateViews: [NSView] { get }
    

    像这样覆盖:

    class CustomRowTemplate: NSPredicateEditorRowTemplate {
    
        override var templateViews: [NSView] {
            get {
                let templateViews = super.templateViews
    
                // custom subclass work goes here
    
                return templateViews
            }
            //set {
    
            // Superclass property is `get` only, other properties might need a setter
    
            //}
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-23
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多