Что делает @objc под капотом? - PullRequest
0 голосов
/ 24 августа 2018

Я не смог найти ничего конкретного в документации Apple.

Вот сценарий.

Класс Objective-C:

@implementation Superclass

- (instancetype)init {
    self = [super init];
    [self doSomething];
    return self;
}

- (void)doSomething {
    NSLog(@"\ndoSomething called from Superclass\n");
}

@end

Swift подкласс:

class Subclass: Superclass {

    override init() {
        super.init()
        doSomething()
    }

    @objc func doSomething() {
        print("\n\ndoSomething called from Subclass\n")
    }

}

Использование @objc в сигнатуре метода doSomething в подклассе приводит к тому, что метод в суперклассе никогда не вызывается, т. Е. Только doSomething called from Subclass выводится на консоль.

Удаление @objc устраняет проблему.

Почему это?

Ответы [ 2 ]

0 голосов
/ 24 августа 2018

Когда @objc используется для объявления класса, это означает, что вы пишете класс Objective-C с помощью Swift.

@ objc, используемый для объявления метода, означает, что вместо swift's String, Dictionary, Notification и т. Д. Фактически будут использоваться Objective-C NSString, NSDictionary, NSNotification и методыстановятся доступными в коде Objective-C.

0 голосов
/ 24 августа 2018

@objc делает метод доступным для среды выполнения Objective C, сравните атрибуты в справочнике по языку Swift. Поэтому

@objc func doSomething()

переопределяет

- (void)doSomething 

метод экземпляра, определенный в суперклассе Objective-C. Следовательно, если self является экземпляром Subclass, то

[self doSomething];

вызывает метод подкласса - независимо от того, где этот вызов выполнен. (Распределение сообщений в Objective-C полностью динамично.) Вот почему метод подкласса вызывается дважды.

Без @objc метод экземпляра Swift невидим для Objective-C, и не переопределяет метод суперкласса.

...