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 № 1Tut
@objc
Schlüsselwort aktivieren Nachrichtenversand sowiedynamic
?
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
.