0

After reading @property/@synthesize equivalent in swift, I became curious for how the functionality from Objective C was retained.

Say I have the following in Objective C:

@interface MyClass
@property (readwrite) MyType *myVar;
@end

This can be accessed like such with dot- and smalltalk-based syntaxes:

Type *newVar1 = myClassInstance.myVar;
Type *newVar2 = [myClassInstance myVar];

myClassInstance.myVar = newVar1;
[myClassInstance setMyVar: newVar2];

And if I want to add some additional functionality to those getters/setters, I can do this:

@implementation MyClass

- (MyType *) myVar
{
    // do more stuff
    return self._myVar;
}

- (void) setMyVar: (MyType *) newVar
{
    self._myVar = newVar;
    // do more stuff
}

@end

(see also Custom setter for @property?)

However, the accepted answer to the above linked question says that Swift doesn't differentiate between properties and instance variable. So, say I have the following in Swift:

class MyClass {
    var myVar: MyType
}

As far as I know, the only way to access myVar is as such:

var newVar1 = myClassInstance.myVar;

myClassInstance.myVar = newVar1;

But I don't know how to customize these getters and setters. Is there a Swift equivalent of the Objective C @property overrides?

Community
  • 1
  • 1
Ky -
  • 30,724
  • 51
  • 192
  • 308

1 Answers1

0

While researching this question, I actually happened upon my answer, but still figured it should be put here for anyone else with the same question.


Yes, according to the Swift Programming Language documentation's page on Properties, getters and setters can be made in a similar way to how C# tackles the problem:

struct MyParentType {
    var myPlainVar: MyType = MyType()
    
    var myCustomGetterVar: MyType {
        // do more stuff
        return self.myCustomGetterVar
    }
    
    var myCustomGetterSetterVar: MyType {
        get {
            // do more stuff
            return self.myCustomGetterSetterVar
        }
        set {
            // do stuff
            self.myCustomGetterSetterVar = newValue
            // do more stuff
        }
    }
    
    var myCustomFancyVar: MyType? {
        willSet {
            // do stuff with newValue
        }
        // actual setting is done automatically, so no set{}
        didSet {
            // do more stuff with oldValue
        }
    }
}

Note that variables with didSet must be initialized or optional, and cannot have a get, since properties which are computed with get can easily implement their own didSet and willSet if they so choose.

Ky -
  • 30,724
  • 51
  • 192
  • 308
  • 1
    You're a bit mixed up when it comes to `willSet`/`didSet`. The `!` you're using is not an unpacking operator – you're declaring `myCustomFancyVar` to be an "implicitly unwrapped optional" i.e. a variable that can have a `nil` value. Since these don't have to be initialized (they default to `nil`), you don't have to give it a default value. But if you gave it an initial value or used an initializer, you would not need the `!`: `struct S { var x: Int = 1 { willSet(newVal) { println("willSet: \(newVal)") } didSet { println("did set") } } }; var s = S(x: 5); s.x = 2` – Airspeed Velocity Apr 01 '15 at 17:43