Swift property override not working

前端 未结 2 1016
挽巷
挽巷 2021-02-07 02:11

When I try to override a property I get an error \"can not override mutable property with read-only property\"

I have provided get and set in the super class.

         


        
相关标签:
2条回答
  • 2021-02-07 02:43

    The compiler error message is fairly straightforward: Card's contents property is mutable, which is to say it has a set method in addition to the get method.

    Your override only adds a get method, you need to add a set method too.

    I think this is what you want:

    set(newValue) {
        rankStrings[Int(self.rank)] = newValue;
    }
    
    0 讨论(0)
  • 2021-02-07 02:58

    If the property you're overriding has both a getter and a setter, you need to provide both in your subclass as well. Here's the relevant part from the Swift language guide (emphasis mine):

    You can present an inherited read-only property as a read-write property by providing both a getter and a setter in your subclass property override. You cannot, however, present an inherited read-write property as a read-only property.

    If you're not doing anything special with the value, then you'll typically want to pass the value being set on to the base class:

    set {
        super.contents = newValue
    }
    

    You could also just discard the value with an empty setter (although I can't think of a good reason to do this offhand):

    set { }
    

    I also wanted to point out that you have an infinite loop in the contents property in your Card class. When you you do this:

    get {
        return self.contents
    }
    

    You're actually just calling that same getter again, creating an infinite loop; you're doing the same with the setter. Swift doesn't create ivars for your properties automatically like Objective-C did, so you need to create them yourself. A more appropriate way to create that property would be to do something like this:

    class Card {
        private var _contents: String
        var contents: String {
            get {
                return _contents
            }
            set {
                _contents = newValue
            }
        }
        init() {
            _contents = ""
        }
    }
    

    However, since you're not doing anything other than setting and returning _contents in your setter and getter, you can simplify it down to this:

    class Card {
        var contents: String = ""
        init() {
    
        }
    }
    

    Note: contents might also be a good candidate for using an optional (String?) and setting it to nil rather than initializing it to an empty string.

    0 讨论(0)
提交回复
热议问题