/ / Zachowanie podklasy rozszerzania słowa kluczowego @objc - swift, swift4, swift4.1

Zachowanie podklasy rozszerzania słowa kluczowego @objc - swift, swift4, swift4.1

Czy ktoś może wyjaśnić dlaczego? @objc słowo kluczowe jest potrzebne tutaj, aby skompilować kod?

Jak rozumiem, to słowo kluczowe jest używane w celu wywołania metody wiadomości ObjC. Ale to nie jest NSObject instancja.

 class MyClass { }
extension MyClass {
@objc func extensionMethod() { /// THIS LINE
print("A")
}
}

class SubClass: MyClass {
override func extensionMethod() {
print("B")
}
}

Robi @objc słowo kluczowe włącza wysyłanie wiadomości, jak również dynamic? Albo nie?

Odpowiedzi:

6 dla odpowiedzi № 1

Robi @objc słowo kluczowe włącza wysyłanie wiadomości, jak również dynamic?

Zazwyczaj nie. Zwykle @objc Sam atrybut po prostu eksponuje danego uczestnika klasy na Objective-C - Swift może nadal wysyłać do niego przy użyciu tabeli lub wysyłki statycznej. Będziesz musiał oznaczyć członka jako dynamic jeśli chcesz, aby Swift używał wysyłania wiadomości podczas jej wywoływania.

Jednak dla nie-końcowego @objc klasa rozbudowa członek, Swift automatycznie wywnioskuje, że jest dynamic. Czemu? Ze względu na interoperacyjność Swift pozwala @objc członkowie rozszerzenia do nadpisania i nadpisania (podobnie jak można zastąpić metodę Obj-C w kategorii podklasy). Aby osiągnąć to zachowanie, Swift opiera się na wysyłce wiadomości Obj-C.

Dlatego w rozszerzeniu @objc infers dynamic. Nie można przesłonić elementu rozszerzenia bezpoddanie go działaniu środowiska wykonawczego Obj-C, ponieważ członkowie rozszerzenia nie mogą obecnie zostać dodani do vtablesów klasy Swift (ponieważ Swift vtables obecnie nie może mieć członków dodawanych dynamicznie do nich w czasie wykonywania).

Ale to nie jest NSObject instancja.

Na platformach Apple (tzn. Z interfejsem Obj-C), wszystko Klasy Swift są narażone na działanie środowiska wykonawczego Obj-C i wszystkie niejawnie dziedziczą ze specjalnej klasy bazowej Obj-C o nazwie _SwiftObject, który jest zgodny z NSObjectProtocol. Tak więc klasy Swift mogą korzystać z wysyłek wiadomości bez konieczności dziedziczenia NSObject.