Создание эквивалентного Getter и Setter Objective-C в Swift

Что эквивалентно следующему Objective-C коду в Swift?

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

В частности, как объявить переменную в Swift для синтеза геттера с пользовательским именем?

Кроме того, как вы можете впоследствии переопределить реализацию getter и setter?

Ответ 1

Ваше предположение было близким, но некоторые вещи можно было изменить. Я постараюсь помочь вам приблизиться к версии Objective-C.

Прежде всего, nonatomic и assign неактуальны в быстром. Это оставляет нам

@property (getter = isOpen) BOOL open;

Так как свойства в swift являются просто переменными экземпляра, быстрый перевод будет следующим.

var open:Bool

Несмотря на то, что он имеет ту же базовую функциональность, что и версия Objective-C, ему не хватает имени getter (isOpen). К сожалению, для этого нет прямого перевода для этого (пока). Вы можете использовать пользовательский getter и setter.

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

Довольно грубая работа заключалась в том, чтобы сделать еще одну функцию, буквально называемую isOpen, которая будет действовать как получатель.

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

В заключение, то, что вы просите, только немного возможно, но, надеюсь, в более поздних версиях быстрой может стать реальностью.

Ответ 2

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

Ведет этот сгенерированный заголовок:

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

Ответ 3

В качестве замечания, для установщика вам нужно повторить директиву @objc:

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

Не забывайте о полуколонне.

Особенность заключается в том, что, делая это, self.open будет вызывать сам self.open/getter и создавать бесконечный цикл. В Obj-C вы исправляете это, используя self->open. Как это сделать, если быстро?