mike
mike

Reputation: 323

Creating an Objective-C equivalent Getter and Setter in Swift

What is the equivalent of the following Objective-C code in Swift?

@property (nonatomic, assign, getter = isOpen) BOOL open;

Specifically, how does one declare a variable in Swift to synthesize the getter with a custom name?

Furthermore, how can you subsequently override the implementation of the getter and setter?

Upvotes: 15

Views: 11474

Answers (3)

tontonCD
tontonCD

Reputation: 358

As a remarq, for the setter you need to repeat the @objc directive:

@objc( setOpen:) set { self.open = newValue }

Don't forguet the semi-column.

A particular thing is that, doing this, self.open will call the setter/getter itself and produce an infinite loop. In Obj-C you fix it using self->open. How do this if swift?

Upvotes: -2

codeperson
codeperson

Reputation: 8050

var open: Bool {
    @objc(isOpen)
    get {
        // custom getter
    }
    set {
        // custom setter
    }
}

Leads to this generated header:

SWIFT_CLASS("_TtC11SwiftToObjC9TestClass")
@interface TestClass : NSObject
@property (nonatomic, getter=isOpen) BOOL open;
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

Upvotes: 20

Brian Tracy
Brian Tracy

Reputation: 6831

Your assumption was close, but a few things could be changed. I will try to help you get as close as possible to the Objective-C version.

First of all, the nonatomic and assign are irrelevant in swift. That leaves us with

@property (getter = isOpen) BOOL open;

Since properties in swift are just instance variables, the swift translation would be as follows.

var open:Bool

Although this has the same basic functionality as the Objective-C version, it is lacking the named getter (isOpen). Unfortunately, there is no direct translation to swift for this (yet). You could use a custom getter and setter.

var open:Bool {
    get {
        // custom getter
    }
    set {
        // custom setter
    }
}

A rather crude work around would be to make another function literally called isOpen that would act as a getter.

func isOpen() -> Bool { return self.open }

In conclusion, what you are asking is only slightly possible, but hopefully in later releases of swift can become a reality.

Upvotes: 19

Related Questions