/ / @objc Verhalten der Schlüsselworterweiterung für Unterklassen - swift, swift4, swift4.1

@objc Schlüsselwort Erweiterung Unterklasse Verhalten - swift, swift4, swift4.1

Kann jemand erklären warum @objc Stichwort wird hier benötigt, um den Code zu kompilieren?

Wie ich verstanden habe, wird dieses Schlüsselwort verwendet, um den Versand von ObjC-Nachrichtenmethoden zu ermöglichen. Aber das ist kein NSObject Beispiel.

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

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

Tut @objc Schlüsselwort aktivieren Nachrichtenversand sowie dynamic? Oder nicht?

Antworten:

6 für die Antwort № 1

Tut @objc Schlüsselwort aktivieren Nachrichtenversand sowie dynamic?

Nicht gewöhnlich. Normalerweise ist die @objc Attribut allein macht ein bestimmtes Klassenmitglied nur für Objective-C verfügbar - Swift kann es weiterhin entweder über die Tabelle oder statisch versenden. Sie müssten das Mitglied als markieren dynamic wenn Sie möchten, dass Swift den Nachrichtenversand verwendet, wenn Sie ihn anrufen.

Allerdings für eine nicht endgültige @objc Klasse Erweiterung Mitglied, wird Swift automatisch daraus schließen dynamic. Warum? Aus Gründen der Interoperabilität erlaubt Swift dies @objc Erweiterungsmitglieder zum Überschreiben und Überschreiben (ähnlich wie Sie eine Obj-C-Methode in einer Unterklassenkategorie überschreiben können). Um dieses Verhalten zu erreichen, verwendet Swift den Obj-C-Nachrichtenversand.

Daher in einer Erweiterung, @objc schließt dynamic. Sie können ein Erweiterungsmitglied ohne nicht überschreibenOffenlegen für die Obj-C-Laufzeit, da Erweiterungsmitglieder derzeit nicht zu Swift-Klassen-vtables hinzugefügt werden können (da Swift-vtables derzeit keine Mitglieder haben können, die zur Laufzeit dynamisch hinzugefügt werden).

Aber das ist kein NSObject Beispiel.

Auf Apple-Plattformen (z. B. mit Obj-C-Interop) alle Swift-Klassen sind für die Obj-C-Laufzeit verfügbar und alle erben implizit von einer speziellen Obj-C-Basisklasse mit dem Namen _SwiftObject, die entspricht NSObjectProtocol. So können Swift-Klassen den Nachrichtenversand nutzen, ohne von ihm erben zu müssen NSObject.