ios 快速覆盖属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28786597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 05:02:46  来源:igfitidea点击:

Overriding properties in swift

iosswiftproperties

提问by Vasyl Khmil

For example a have a first class

例如有一个头等舱

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

And inherited class:

和继承的类:

public class SomeButton: SomeBaseButton {

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

So, the logic is that SomeClassdefine own text and weight. But I'm getting an errors:

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

For text: "Cannot override with a stored property 'text'"

对于文本:“无法用存储的属性‘文本’覆盖

For weight: "Cannot override with a stored property 'weight'"

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

回答by Stefan Arentz

Interestingly this works just fine in pure Swift classes. For example, this works as expected:

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

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

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

The reason it does not work for you is because you are working with Objective-C classes: since UIButtonis an Objective-C class, all its subclasses will be too. Because of that, the rules seem to be a bit different.

它对您不起作用的原因是因为您正在使用 Objective-C 类:因为它UIButton是一个 Objective-C 类,它的所有子类也将如此。因此,规则似乎有点不同。

Xcode 6.3 is actually a bit more informative. It shows the following two errors:

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

Getter for "weight" overrides Objective-C method "weight" from superclass "FooButton" Setter for "weight" overrides Objective-C method "setWeight:" from superclass "Foobutton"

“weight”的Getter覆盖超类“FooButton”的Objective-C方法“weight”“weight”的Setter覆盖超类“Foobutton”的Objective-C方法“setWeight:”

Since the following does work ...

由于以下确实有效......

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

... my guess is that these methods are simply not synthesized correctly.

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

I wonder if this is a compiler bug. Or a shortcoming. Because I think it couldhandle the case.

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

Maybe the Swift designers thought that in case of overriding weightyou could also simply set it to a different value in your initializer. Hm.

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

回答by onmyway133

In addition, if someone wants to override property to have dynamiceffect, see KVO

另外,如果有人想覆盖属性dynamic生效,见KVO

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

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

回答by Aggressor

In the above you have a getter and a setter.

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

When you override it, you are just assigning it a value.

当您覆盖它时,您只是为其分配了一个值。

Instead set up the setter and getter as you have above.

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

var _text:Text

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

回答by pkamb

I ran into this issue when trying to override the NSPredicateRowEditor templateViewsproperty in Swift 3.

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

Superclass property to override:

要覆盖的超类属性:

open var templateViews: [NSView] { get }

Override like so:

像这样覆盖:

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

        //}
    }

}