In Objective C haben Sie das Konzept, Nachrichten an andere Objekte zu senden, und dies ist sehr ähnlich zu Methodenaufrufen in Sprachen wie C # und Java.
Aber was genau sind die subtilen Unterschiede? Wie sollte ich an Nachrichten denken, wenn ich an meinen Code denke?
Hinweis: Nur ein bisschen Hintergrundwissen, ich bin ein C # / Java-Entwickler, der versucht, einige Konzepte zu Objective C zu verstehen.
Antworten:
Eine Nachricht ist der Name eines Selektors und die Parameter für diesen Selektor.
Ein Selektor ist ein Symbol.
Eine Methode ist ein Stück Code in einer Klasse, die durch einen Selektor identifiziert wird.
Mit anderen Worten
[foo bar: baz]
: "Senden Sie die@selector(bar:)
mit parameter aufgerufene Nachrichtbaz
an objectfoo
. Sie können diese Nachricht an viele verschiedene Objekte senden.Im Gegensatz dazu könnte die Methode
bar:
für a soFoo
aussehenaber für eine
FooTwo
könnte aussehen(Ich hoffe, ich habe die richtige Syntax; es ist schon eine Weile her, seit ich Objective-C das letzte Mal berührt habe.)
Wenn Sie die Nachricht senden, leitet der Objective-C-Kernel die Nachricht weiter, an
foo
die entschieden wird, ob die Nachricht verstanden wird. Dies wird basierend darauf entschieden, ob eine von diesem Selektor identifizierte Methode gefunden wird.Zwei gleichnamige Methoden und eine Meldung.
Es ist auch möglich, dass ein Objekt eine bestimmte Nachricht (oder eine Reihe von Nachrichten) zur Verarbeitung einfach an ein anderes Objekt weiterleitet. In diesem Fall senden Sie eine Nachricht an dieses Proxy-Objekt, für das es keine entsprechenden Methoden gibt , und der Proxy leitet die Nachricht an das umschlossene Objekt weiter.
quelle
Rein theoretisch gesehen gibt es keinen Unterschied zwischen den beiden - es gab eine Reihe formaler Beweise dafür, dass die beiden völlig gleichwertig sind und beide vollständig im Hinblick auf die anderen implementiert werden können.
Aus einer etwas weniger theoretischen Sicht gibt es einen möglichen Unterschied: In einer typischen Implementierung wird die virtuelle Funktionstabelle statisch zugewiesen und der Inhalt jeder vtable wird zur Kompilierungszeit festgelegt. Im Gegensatz dazu wird die Nachrichtensuche in der Regel mit einem map-ähnlichen Objekt durchgeführt, das in der Regel dynamisch ist und das heißt, Sie können es zur Laufzeit ändern. Dadurch ist es relativ einfach, einer Nachricht in einer vorhandenen Klasse eine neue Antwort hinzuzufügen. Leider bleibt dies in den meisten Fällen meist theoretisch. Zuerst Sie es zu tun im Grunde mit selbst-modifizierenden Code, der die meisten Menschen entschieden eine ziemlich schlechte Idee war eine langevor einiger Zeit. Zweitens, um es sehr aussagekräftig zu machen, müssen Sie in der Lage sein, neuen Code in die vorhandene Klasse zu kompilieren, um auf die neue Nachricht zu antworten, die Sie unterstützen. Andernfalls können Sie einer vorhandenen Methode nur dynamisch einen neuen Namen hinzufügen.
Wie am Ende des vorhergehenden Abschnitts angedeutet, gibt es unter einem wirklich praktischen Gesichtspunkt kaum einen Unterschied zwischen den beiden. Es handelt sich lediglich um zwei (sehr geringfügig) unterschiedliche Möglichkeiten, das späte Binden zu unterstützen. Obwohl die nachrichtenbasierte Suche im Allgemeinen etwas langsamer ist, ist es ziemlich ungewöhnlich, dass der Unterschied wirklich signifikant ist. Für die meisten praktischen Zwecke gibt es nur zwei verschiedene Möglichkeiten, um dasselbe Ziel zu erreichen.
quelle
In Objective-C sind Nachrichten spät gebunden. Das heißt, sie werden zur Laufzeit aufgelöst. C # unterstützt ein ähnliches Konstrukt über das Schlüsselwort Dynamic, das ein Objekt auch als spät gebunden deklariert.
quelle
Normalerweise werden Methodenaufrufe zur Kompilierungszeit aufgelöst (es sei denn, Sie verwenden Reflection in Java), während Nachrichten in Objective C zur Laufzeit abgesetzt werden.
quelle
struct
als ersten Parameter verwenden. Die späte Bindung ist ein wesentlicher Bestandteil des Polymorphismus und damit des OOP.Nachrichten werden entweder vom Kernel oder von der Sprache selbst verarbeitet (für ObjC gibt es beispielsweise einen sehr kleinen Assembler-Code, der dies erledigt).
Im Linux-Kernel werden Nachrichten beispielsweise mit Systemaufrufen / function erstellt: Sie können sie finden, wenn Sie nach Unix-Systemprogrammierung suchen.
Der Hauptunterschied zwischen einem Methodenaufruf und einer Nachricht ist folgender:
Ein Methodenaufruf tritt nur in Ihrem Code auf: In ASM wird er durch ein PUSH der übergebenen Argumente übersetzt.
Eine Kernel-Nachricht ist meistens etwas, das an den Kernel gesendet wird, der verfolgt und an einen bestimmten Prozess zurückgesendet wird. Ich verwechsle sie vielleicht mit Pipes, aber wie auch immer: Wissen Sie, dass es bereits Mechanismen gibt, mit denen Sie mehrere Programme gleichzeitig ausführen und gleichzeitig kommunizieren lassen können. Hoffen Sie natürlich nicht, dass dies unter Windows oder anderen Betriebssystemen genauso funktioniert.
quelle