swift setter causing exc_bad_access

后端 未结 3 1750
青春惊慌失措
青春惊慌失措 2020-12-07 01:49

I have a simple class below

import Foundation

public class UsefulClass: NSObject{
    var test:NSNumber{
        get{return self.test}
        set{
                


        
相关标签:
3条回答
  • 2020-12-07 02:21

    Swift variables are synthesized properties by default. In the most cases this is sufficient (it's recommended to prefer Swift types)

    var test: Int
    
    override init() {
        super.init()
        test = 5
    }
    

    If you need to do something after a variable is set, use

    var test: Int {
        didSet{
            println("\(oldValue) - \(newValue)")
        }
    }
    

    your code sets the variable permanently by calling the setter which calls the setter which …

    0 讨论(0)
  • 2020-12-07 02:21

    It's an infinite loop; your setter is recursively calling itself.

    var test: NSNumber {
        set {
            test = newValue
        }
    }
    

    This compiles fine, and an Objective-C programmer might expect no loop due to instead setting a "backing ivar" such as _test rather than re-calling the setter method.

    But property-backing instance variable _ivars do not exist in Swift for computed properties unless you create them yourself.

    0 讨论(0)
  • 2020-12-07 02:25

    @vadian has provided a solution in his answer, which should fix your problem. Let me just explain what's happening.

    You have created a computed property, i.e. a property which is not backed by a variable, instead both the getter and the setter do some processing, usually on another stored property, in order to respectively return a value and set a new value.

    This is your computed property:

    var test: NSNumber {
        get { return self.test }
        set {
            println(newValue)
            self.test = newValue
        }
    }
    

    Look at the getter implementation:

    return self.test
    

    What does it do? It reads the test property of the current instance, and returns it. Which is the test property? It's this one:

    var test: NSNumber {
        get { return self.test }
        set {
            println(newValue)
            self.test = newValue
        }
    }
    

    Yes, it's the same property. What your getter does is to recursively and indefinitely calling itself, until a crash happen at runtime.

    The same rule applies to the setter:

    self.test = newValue 
    

    it keeps invoking itself, until the app crashes.

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