31

I am converting a project in to Swift code and have come across an issue in a setter. My Objective-C code looked like this:

- (void)setDocument:(MyDocument *)document
{
    if (![_document isEqual:document]) {
        _document = document;

        [self useDocument];
    }
}

and allowed my View Controller to run this each time the document was set (typically in the prepareForSegue: method of the presenting View Controller).

I have found the property observers willSet and didSet but they only work when the property is being updated, not when it’s initialised and updated.

Any ideas? Thanks

UPDATE

after trying get{} and set{} I get the EXC_BAD_ACCESS error

var document: UIDocument? {
    get {
        return self.document!
    }
    set {
        self.document = newValue

        useDocument()
    }
}
Adam Carter
  • 4,741
  • 5
  • 42
  • 103
  • Don't use the property observers. Use get { } and get { }. Check out the Computed Properties section [here](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html). – Mick MacCallum Sep 13 '14 at 23:17
  • Possible duplicate of [How to override setter in Swift](https://stackoverflow.com/questions/36440631/how-to-override-setter-in-swift) – BB9z Nov 27 '18 at 10:59

2 Answers2

53

You can't use set like that because when you call self.document = newValue you're just calling the setter again; you've created an infinite loop.

What you have to do instead is create a separate property to actually store the value in:

private var _document: UIDocument? = nil
var document: UIDocument? {
    get {
        return self._document
    }
    set {
        self._document = newValue
        useDocument()
    }
}
Mike S
  • 41,895
  • 11
  • 89
  • 84
  • 22
    I don't understand why the compiler asks explicitly to add self into the setter if the result will be an infinite loop. I am the only one here to think it is not an elegant solution to use a private var ? A getter and setter function will make a better job – Mr Bonjour May 15 '15 at 14:17
  • 4
    Swift is a work in progress. There are many little things like this, which I hope that Apple makes the compiler automatically do the dirty work for you so that you can just concentrate on coding instead of constantly being like "arrrrgh" – CommaToast Jan 23 '16 at 18:29
  • Any updates for swift 3 so far ? left an up-vote anyway. – belafarinrod91 Jan 09 '17 at 15:16
  • 3
    This definitively lack of some magic here. Kotlin has the `field` backing field to handle custom getters and setters. – ndelanou Mar 25 '20 at 14:30
14

Here's a Swift 3 version

var document : UIDocument? {
    didSet {
        useDocument()
    }
}
John Stephen
  • 7,625
  • 2
  • 31
  • 45