Punktnotation vs. Nachrichtennotation für deklarierte Eigenschaften

81

Wir haben jetzt die "Punkt" -Notation für Eigenschaften. Ich habe verschiedene Hin- und Herbewegungen über die Vorzüge der Punktnotation gegenüber der Nachrichtennotation gesehen. Um die Antworten nicht zu beeinträchtigen, werde ich in der Frage nicht so oder so antworten.

Was halten Sie von der Punktnotation im Vergleich zur Nachrichtennotation für den Zugriff auf Eigenschaften?

Bitte versuchen Sie, es auf Objective-C zu konzentrieren - meine einzige Tendenz, die ich hervorheben werde, ist, dass Objective-C Objective-C ist, sodass Ihre Präferenz, dass es wie Java oder JavaScript ist, nicht gültig ist.

Ein gültiger Kommentar bezieht sich auf technische Probleme (Reihenfolge der Operationen, Priorität der Besetzung, Leistung usw.), Klarheit (Struktur vs. Objektnatur, sowohl für als auch für!), Prägnanz usw.

Beachten Sie, dass ich von der Schule der strengen Qualität und Lesbarkeit von Code bin und an großen Projekten gearbeitet habe, bei denen Codekonvention und -qualität von größter Bedeutung sind (das Schreiben hat einmal tausendmal gelesenes Paradigma).

Murmeltier
quelle
14
+1 Dies ist eine großartige Frage, und Sie werden viele widersprüchliche Antworten erhalten. =)
Dave DeLong
1
Der Quellcode-Editor sollte sich an die persönlichen Vorlieben des Programmierers anpassen, ohne die Zeichen der Datei selbst zu ändern. Auf diese Weise würde jeder bekommen, was er mag.
Arne Evertsson

Antworten:

64

Verwenden Sie keinen Punkt für das Verhalten. Verwenden Sie dot, um auf Attribute wie Inhalte zuzugreifen oder diese festzulegen, normalerweise Attribute, die als Eigenschaften deklariert sind.

x = foo.name; // good
foo.age = 42; // good

y = x.retain; // bad

k.release; // compiler should warn, but some don't. Oops.

v.lockFocusIfCanDraw; /// ooh... no. bad bad bad

Für Leute, die neu in Objective-C sind, würde ich empfehlen, den Punkt nur für Dinge zu verwenden, die als @property deklariert sind. Wenn Sie ein Gefühl für die Sprache haben, tun Sie, was sich richtig anfühlt.

Zum Beispiel finde ich Folgendes vollkommen natürlich:

k = anArray.count;
for (NSView *v in myView.subviews) { ... };

Sie können davon ausgehen, dass der statische Clang-Analysator die Möglichkeit erweitert, zu überprüfen, ob der Punkt nur für bestimmte Muster oder nicht für bestimmte andere Muster verwendet wird.

bbum
quelle
18
Wow, ich wusste nicht einmal, dass Sie die Punktsyntax für etwas anderes als Eigenschaften verwenden können. Färbe mich überrascht! (Aber ich stimme zu, Punkt sollte nur für Eigenschaften verwendet werden)
jbrennan
13
Das ist falsch. Die Punktnotation ist ein einfaches Synonym für einen äquivalenten Methodenaufruf. nicht mehr, nicht weniger.
bbum
2
Ich frage mich, warum die Punktnotation nicht auf @ Eigenschaft-deklarierte Accessoren beschränkt war. Es scheint, als hätte es Klassenautoren ermöglicht, Grauzonen aufzulösen, über die Methoden in Punktnotation zulässig sein sollten, und es wäre nicht so zweideutig, ob Methoden verwendet werden sollten oder nicht, als .uppercaseStringob die Klasse ihre Absicht ausdrücken und haben dürfe vom Compiler erzwungen. Vielleicht fehlt mir etwas, das die aktuelle Implementierung der Punktnotation erfordert.
4
Es hätte nur beschränkt sein können, @propertyaber das würde sowohl erfordern, dass der Verbraucher einer API eine andere boolesche Dimension von Informationen lernt, als auch Entwickler von API in Argumenten darüber ertrinken, was eine sein sollte und was nicht @property. Beachten Sie, dass Xcode @propertybeim Vervollständigen von Code implizite Methoden bevorzugt - stärker gewichtet - . Es wird empfohlen, aber nicht erzwungen.
bbum
1
@rodamn Es beantwortet das; Es wird empfohlen, den Punkt nur mit @propertydeklarierten Accessoren zu verwenden, wenn die Sprache neu ist. Wenn Sie Vertrauen in die Codierung in Objective-C gewinnen, tun Sie, was sich richtig anfühlt. Interessant; Viele von uns haben sich auf eine sehr, sehr eingeschränkte Verwendung des Punktes beschränkt.
bbum
22

Lassen Sie mich zunächst sagen, dass ich mit der Programmierung in Visual / Real Basic begonnen und dann zu Java übergegangen bin, sodass ich die Punktsyntax ziemlich gewohnt bin. Als ich jedoch schließlich zu Objective-C wechselte und mich an Klammern gewöhnte und dann die Einführung von Objective-C 2.0 und seiner Punktsyntax sah, stellte ich fest, dass es mir wirklich nicht gefällt. (Für andere Sprachen ist es in Ordnung, denn so rollen sie).

Ich habe drei Haupt-Beefs mit Punktsyntax in Objective-C:

Rindfleisch Nr. 1: Es macht unklar, warum Sie möglicherweise Fehler erhalten. Zum Beispiel, wenn ich die Zeile habe:

something.frame.origin.x = 42;

Dann erhalte ich einen Compilerfehler, da somethinges sich um ein Objekt handelt und Sie die Strukturen eines Objekts nicht als Wert eines Ausdrucks verwenden können. Wenn ich jedoch:

something.frame.origin.x = 42;

Dann wird dies gut kompiliert, da somethinges sich um eine Struktur handelt, die ein NSRect-Mitglied hat, und ich kann sie als Wert verwenden.

Wenn ich diesen Code übernehmen würde, müsste ich einige Zeit damit verbringen, herauszufinden, was somethingist. Ist es eine Struktur? Ist es ein Objekt? Wenn wir jedoch die Klammer-Syntax verwenden, ist es viel klarer:

[something setFrame:newFrame];

In diesem Fall gibt es absolut keine Mehrdeutigkeit, ob somethinges sich um ein Objekt handelt oder nicht. Die Einführung von Mehrdeutigkeit ist mein Rindfleisch Nr. 1.

Beef # 2: In C wird die Punktsyntax verwendet, um auf Mitglieder von Strukturen zuzugreifen, nicht um Methoden aufzurufen. Programmierer können die setFoo:und fooMethoden eines Objekts überschreiben und dennoch über auf sie zugreifen something.foo. Wenn ich Ausdrücke mit Punktsyntax sehe, erwarte ich, dass sie eine einfache Zuordnung zu einem Ivar darstellen. Dies ist nicht immer der Fall. Stellen Sie sich ein Controller-Objekt vor, das ein Array und eine Tabellenansicht vermittelt. Wenn ich anrufe myController.contentArray = newArray;, würde ich erwarten, dass das alte Array durch das neue Array ersetzt wird. Der ursprüngliche Programmierer hat jedoch möglicherweise überschrieben, setContentArray:um nicht nur das Array festzulegen, sondern auch die Tabellenansicht neu zu laden. Aus der Zeile gibt es keinen Hinweis auf dieses Verhalten. Wenn ich sehen würde[myController setContentArray:newArray];Dann würde ich denken: "Aha, eine Methode. Ich muss mir die Definition dieser Methode ansehen, um sicherzugehen, dass ich weiß, was sie tut."

Ich denke, meine Zusammenfassung von Beef # 2 ist, dass Sie die Bedeutung der Punktsyntax mit benutzerdefiniertem Code überschreiben können.

Rindfleisch Nr. 3: Ich denke, es sieht schlecht aus. Als Objective-C-Programmierer bin ich es gewohnt, die Syntax in Klammern zu setzen. Es foo.name = newName; foo.size = newSize;ist also ein bisschen ablenkend, mitzulesen und Linien und Linien mit schönen Klammern zu sehen und dann plötzlich mit usw. gebrochen zu werden. Mir ist klar, dass einige Dinge Punktsyntax (C-Strukturen) erfordern, aber das ist das einzige Mal, dass ich sie benutze.

Wenn Sie Code für sich selbst schreiben, verwenden Sie natürlich alles, was Sie möchten. Wenn Sie jedoch Code schreiben, den Sie für Open Sourcing planen, oder etwas schreiben, von dem Sie nicht erwarten, dass es für immer beibehalten wird, würde ich die Verwendung der Klammer-Syntax nachdrücklich empfehlen. Dies ist natürlich nur meine Meinung.

Letzter Blog-Beitrag gegen Punktsyntax: http://weblog.bignerdranch.com/?p=83

Gegenargument zum obigen Beitrag: http://eschatologist.net/blog/?p=226 (mit Originalartikel zugunsten der Punktsyntax : http://eschatologist.net/blog/?p=160 )

Dave DeLong
quelle
5
Rindfleisch Nr. 1 scheint mir ein wenig fadenscheinig zu sein. Ich sehe nicht, dass dies ein Problem ist, genauso wenig wie Sie versuchen könnten, eine Nachricht an eine Struktur zu senden, und dann herausfinden müssen, dass die Variable tatsächlich eine Struktur ist. Sehen Sie tatsächlich viele Leute, die verstehen, wie es funktioniert, in der Praxis verwirrt zu werden? Dies scheint die Art von Dingen zu sein, die Sie einmal durcheinander bringen, etwas über den Wert lernen und es dann in Zukunft richtig machen würden - so als würden Sie beispielsweise nicht versuchen, NSNumbers wie Ints zu behandeln.
Chuck
2
@Chuck, es ist ein Randfall, aber ich mache ziemlich viel Vertragsentwicklung, bei der Projekte geerbt werden und mit ihnen gearbeitet werden muss. Normalerweise something handelt es sich um ein Objekt, aber ich bin auf einige Stellen gestoßen, an denen die ursprünglichen Autoren Strukturen erstellt haben (für Geschwindigkeit, geringere Speichernutzung usw.), und ich muss ein paar Minuten damit verbringen, herauszufinden, warum der Code nicht funktioniert. t kompilieren.
Dave DeLong
14

Ich bin ein neuer Cocoa / Objective-C-Entwickler und sehe das folgendermaßen:

Ich halte mich an die Messaging-Notation, obwohl ich mit Obj-C 2.0 angefangen habe und obwohl die Punktnotation ein vertrauteres Gefühl ist (Java ist meine Muttersprache). Mein Grund dafür ist ziemlich einfach: Ich verstehe immer noch nicht genau warum sie der Sprache die Punktnotation hinzugefügt haben. Für mich scheint es eine unnötige, "unreine" Ergänzung zu sein. Wenn jemand erklären kann, wie es der Sprache zugute kommt, würde ich mich freuen, es zu hören.

Ich halte dies jedoch für eine stilistische Wahl, und ich glaube nicht, dass es einen richtigen oder falschen Weg gibt, solange er konsistent und lesbar ist , genau wie bei jeder anderen stilistischen Wahl (z. B. wenn Sie Ihre öffnende geschweifte Klammer auf dieselbe Linie setzen wie den Methodenkopf oder die nächste Zeile).

Ellie P.
quelle
2
+1 tolle Antwort. Ich würde wirklich gerne auch das "Warum" dahinter wissen. Vielleicht kennt bbum oder mmalc die Antwort ... (beide arbeiten bei )
Dave DeLong
11

Die Objective-C-Punktnotation ist ein syntaktischer Zucker, der in die normale Nachrichtenübermittlung übersetzt wird. Unter der Haube ändert sich also nichts und macht zur Laufzeit keinen Unterschied. Punktnotation ist absolut nicht schneller als das Weiterleiten von Nachrichten.

Danach brauchte ich eine kleine Präambel: Hier sind die Vor- und Nachteile, die ich gesehen habe:

Vor- und Nachteile der Punktnotation

  • Profis

    • Lesbarkeit: Die Punktnotation ist leichter zu lesen als Massagen in verschachtelten Klammern
    • Es vereinfacht die Interaktion mit Attributen und Eigenschaften: Mithilfe der Punktnotation für Eigenschaften und der Nachrichtennotation für Methoden können Sie eine Trennung von Status und Verhalten auf Synthaxebene erreichen
    • Es ist möglich, den zusammengesetzten Zuweisungsoperator (1) zu verwenden .
    • Mit der @propertyNotation und der Punktnotation erledigt der Compiler viel Arbeit für Sie. Er kann Code für eine gute Speicherverwaltung beim Abrufen und Festlegen der Eigenschaft generieren. Aus diesem Grund wird die Punktnotation von den offiziellen Leitfäden von Apple selbst vorgeschlagen.
  • Nachteile

    • Die Punktnotation ist nur für den Zugriff auf eine deklarierte zulässig @property
    • Da Objective-C eine Ebene über Standard C (Spracherweiterung) ist, macht die Punktnotation nicht wirklich klar, ob es sich bei der Entität, auf die zugegriffen wird, um ein Objekt oder eine Struktur handelt. Oft sieht es so aus, als würden Sie auf Eigenschaften einer Struktur zugreifen.
    • Wenn Sie eine Methode mit der Punktnotation aufrufen, verlieren Sie die Lesbarkeitsvorteile für benannte Parameter
    • Wenn die gemischte Notation von Nachrichten und Punkten so aussieht, als würden Sie in zwei verschiedenen Sprachen codieren

Codebeispiele:

(1) Beispiel für einen zusammengesetzten Operator-Verwendungscode:

//Use of compound operator on a property of an object
anObject.var += 1;
//This is not possible with standard message notation
[anObject setVar:[anObject var] + 1];
Aleroot
quelle
7

Die Verwendung des Stils einer Sprache, der mit der Sprache selbst übereinstimmt, ist hier der beste Rat. Dies ist jedoch kein Fall des Schreibens von Funktionscode in einem OO-System (oder umgekehrt), und die Punktnotation ist Teil der Syntax in Objective-C 2.0.

Jedes System kann missbraucht werden. Die Existenz des Präprozessors in allen C-basierten Sprachen reicht aus, um wirklich seltsame Dinge zu tun. Schauen Sie sich einfach den Obfuscated C Contest an, wenn Sie genau sehen möchten, wie seltsam es werden kann. Bedeutet das, dass der Präprozessor automatisch fehlerhaft ist und Sie ihn niemals verwenden sollten?

Die Verwendung der Punktsyntax für den Zugriff auf Eigenschaften, die in der Benutzeroberfläche als solche definiert wurden, kann missbraucht werden. Die Existenz von Missbrauch in Potentia sollte nicht unbedingt das Argument dagegen sein.

Der Zugang zu Immobilien kann Nebenwirkungen haben. Dies ist orthogonal zu der Syntax, mit der diese Eigenschaft erfasst wird. CoreData, Delegation und dynamische Eigenschaften (first + last = full) erledigen alle Arbeiten im Verborgenen. Dies würde jedoch "Instanzvariablen" mit "Eigenschaften" eines Objekts verwechseln. Es gibt keinen Grund, warum Eigenschaften unbedingt unverändert gespeichert werden müssen, insbesondere wenn sie berechnet werden können (z. B. Länge eines Strings). Unabhängig davon, ob Sie foo.fullName oder [foo fullName] verwenden, wird es immer noch eine dynamische Auswertung geben.

Schließlich wird das Verhalten der Eigenschaft (wenn sie als Wert verwendet wird ) vom Objekt selbst definiert, z. B. ob eine Kopie erstellt oder beibehalten wird. Dies macht es einfacher, das Verhalten später - in der Eigenschaftsdefinition selbst - zu ändern, als Methoden erneut implementieren zu müssen. Dies erhöht die Flexibilität des Ansatzes, was dazu führt, dass weniger (Implementierungs-) Fehler auftreten. Es besteht immer noch die Möglichkeit, die falsche Methode zu wählen (dh kopieren statt beibehalten), aber das ist eher ein Architektur- als ein Implementierungsproblem.

Letztendlich läuft es auf die Frage hinaus, ob es wie eine Struktur aussieht. Dies ist wahrscheinlich das Hauptunterscheidungsmerkmal in den bisherigen Debatten; Wenn Sie eine Struktur haben, funktioniert dies anders als wenn Sie ein Objekt haben. Aber das war schon immer so. Sie können einer Struktur keine Nachricht senden, und Sie müssen wissen, ob sie stapelbasiert oder referenz- / malloc-basiert ist. Es gibt bereits mentale Modelle, die sich in der Verwendung unterscheiden ([[CGRect alloc] init] oder struct CGRect?). Sie waren in Bezug auf das Verhalten nie einheitlich. Sie müssen wissen, womit Sie es jeweils zu tun haben. Es ist sehr unwahrscheinlich, dass das Hinzufügen von Eigenschaftsbezeichnungen für Objekte einen Programmierer verwirrt, der seine Datentypen kennt. und wenn nicht, haben sie größere Probleme.

Was die Konsistenz betrifft; (Ziel-) C ist in sich inkonsistent. = wird sowohl für die Zuweisung als auch für die Gleichheit verwendet, basierend auf der lexikalischen Position im Quellcode. * wird für Zeiger und Multiplikation verwendet. BOOLs sind Zeichen, keine Bytes (oder andere ganzzahlige Werte), obwohl YES und NO 1 bzw. 0 sind. Konsistenz oder Reinheit sind nicht das, wofür die Sprache entwickelt wurde. Es ging darum, Dinge zu erledigen.

Wenn Sie es also nicht verwenden möchten, verwenden Sie es nicht. Mach es anders. Wenn Sie es verwenden möchten und Sie es verstehen, ist es in Ordnung, wenn Sie es verwenden. Andere Sprachen befassen sich mit den Konzepten generischer Datenstrukturen (Maps / Strukturen) und Objekttypen (mit Eigenschaften) und verwenden häufig dieselbe Syntax für beide, obwohl eine lediglich eine Datenstruktur und die andere ein reichhaltiges Objekt ist. Programmierer in Objective-C sollten über die gleiche Fähigkeit verfügen, mit allen Programmierstilen umgehen zu können, auch wenn dies nicht Ihre bevorzugte ist.

AlBlue
quelle
6

Ich benutze es für Eigenschaften, weil

for ( Person *person in group.people){ ... }

ist etwas leichter zu lesen als

for ( Person *person in [group  people]){ ... }

Im zweiten Fall wird die Lesbarkeit unterbrochen, indem Ihr Gehirn in den Nachrichtensende-Modus versetzt wird, während im ersten Fall klar ist, dass Sie auf die Eigenschaft people des Gruppenobjekts zugreifen.

Ich werde es auch verwenden, wenn ich eine Sammlung ändere, zum Beispiel:

[group.people addObject:another_person];

ist etwas lesbarer als

[[group people] addObject:another_person];

In diesem Fall sollte der Schwerpunkt auf dem Hinzufügen eines Objekts zum Array liegen, anstatt zwei Nachrichten zu verketten.

rebo
quelle
5

Ich bin größtenteils im Objective-C 2.0-Zeitalter aufgewachsen und bevorzuge die Punktnotation. Für mich ermöglicht es die Vereinfachung von Code, anstatt zusätzliche Klammern zu haben, kann ich einfach einen Punkt verwenden.

Ich mag auch die Punktsyntax, weil ich das Gefühl habe, auf eine Eigenschaft des Objekts zuzugreifen, anstatt nur eine Nachricht zu senden (natürlich wird die Punktsyntax wirklich zum Senden von Nachrichten übersetzt, aber aus Gründen des Aussehens fühlt sich der Punkt anders an). Anstatt nach der alten Syntax "einen Getter aufzurufen", fühlt es sich wirklich so an, als würde ich direkt etwas Nützliches aus dem Objekt herausholen.

Ein Teil der Debatte darüber befasst sich mit "Aber wir haben bereits Punktsyntax und es ist für structs!". Und das stimmt. Aber (und wieder, das ist nur psychologisch) es fühlt sich für mich im Grunde genauso an. Eine Eigenschaft eines Objekts unter Verwendung von Dot-Syntax Zugriff fühlt das gleiche wie ein Mitglied eines struct zugreifen, die mehr oder weniger die beabsichtigte Wirkung (meiner Meinung) ist.

**** Bearbeiten: Wie bbum hervorhob, können Sie auch die Punktsyntax verwenden, um eine beliebige Methode für ein Objekt aufzurufen (das war mir nicht bekannt). Daher werde ich sagen, dass meine Meinung zur Punktsyntax nur für den Umgang mit Eigenschaften eines Objekts gilt, nicht für das tägliche Senden von Nachrichten **

jbrennan
quelle
3

Ich bevorzuge die Messaging-Syntax sehr ... aber nur, weil ich das gelernt habe. In Anbetracht vieler meiner Klassen und was nicht im Objective-C 1.0-Stil ist, würde ich sie nicht mischen wollen. Ich habe keinen wirklichen Grund außer "was ich gewohnt bin", die Punktsyntax nicht zu verwenden ... AUSSER das macht mich wahnsinnig

[myInstance.methodThatReturnsAnObject sendAMessageToIt]

Ich weiß nicht warum, aber es macht mich wirklich wütend, ohne guten Grund. Ich denke nur, dass das so ist

[[myInstance methodThatReturnsAnObject] sendAMessageToIt]

ist besser lesbar. Aber jedem sein eigenes!

micmoo
quelle
3
Ich mache das von Zeit zu Zeit, aber nur, wenn ich auf eine Immobilie zugreife. Zum Beispiel: [self.title lowercaseString]oder so. Aber ich kann stilistisch sehen, warum es lästig ist, die Syntax zu mischen und anzupassen. Der einzige Grund, warum ich das mache, ist, klar zu halten, was eine Eigenschaft ist und welche Methode ein Objekt zurückgibt (ich weiß, dass Eigenschaften wirklich genau das sind, aber Sie verstehen hoffentlich, was ich meine).
Jbrennan
3

Ehrlich gesagt denke ich, dass es auf den Stil ankommt. Ich persönlich bin gegen die Punktsyntax (insbesondere nachdem ich herausgefunden habe, dass Sie sie für Methodenaufrufe und nicht nur zum Lesen / Schreiben von Variablen verwenden können). Allerdings, wenn Sie gehen , um es zu benutzen, würde ich stark empfehlen nicht verwenden es für etwas anderes als den Zugriff auf und Variablen zu ändern.


quelle
3

Einer der Hauptvorteile der objektorientierten Programmierung besteht darin, dass kein direkter Zugriff auf den internen Zustand der Objekte besteht.

Die Punktsyntax scheint mir ein Versuch zu sein, sie so aussehen zu lassen, als würde direkt auf den Status zugegriffen. Aber in Wahrheit ist es nur syntaktischer Zucker über die Verhaltensweisen -foo und -setFoo:. Ich selbst nenne einen Spaten lieber einen Spaten. Die Punktsyntax verbessert die Lesbarkeit in dem Maße, in dem der Code prägnanter ist, hilft jedoch nicht beim Verständnis, da nicht berücksichtigt wird, dass Sie wirklich -foo und -setFoo aufrufen: Dies kann zu Problemen führen.

Synthetisierte Accessoren scheinen mir ein Versuch zu sein, das Schreiben von Objekten, auf die direkt zugegriffen wird, zu vereinfachen. Ich glaube, dass dies genau die Art von Programmdesign fördert, die durch objektorientierte Programmierung vermieden wurde.

Alles in allem würde ich lieber Punktsyntax und Eigenschaften nie eingeführt worden. Früher konnte ich den Leuten sagen, dass ObjC ein paar saubere Erweiterungen von C sind, um es Smalltalk ähnlicher zu machen, und ich denke, das stimmt nicht mehr.

Hutmütze
quelle
2

Meiner Meinung nach macht die Punktsyntax Objective-C weniger Smalltalk-artig. Dadurch kann Code einfacher aussehen, es wird jedoch mehrdeutig. Ist es ein struct, unionoder ein Objekt?

Dreamlax
quelle
2

Viele Leute scheinen 'Eigenschaften' mit 'Instanzvariablen' zu verwechseln. Der Sinn der Eigenschaften besteht darin, es zu ermöglichen, das Objekt zu modifizieren, ohne seine Interna kennen zu müssen, denke ich. Die Instanzvariable ist meistens die 'Implementierung' einer Eigenschaft (die wiederum die 'Schnittstelle' ist), aber nicht immer: Manchmal entspricht eine Eigenschaft nicht einem ivar und berechnet stattdessen einen Rückgabewert. ' on the fly '.

Aus diesem Grund glaube ich, dass die Idee, dass "die Punktsyntax Sie dazu verleitet zu glauben, dass Sie auf die Variable zugreifen, so dass sie verwirrend ist", falsch ist. Punkt oder Klammer, Sie sollten keine Annahmen über die Interna machen: Es ist eine Eigenschaft, kein Ivar.

Nicolas Miari
quelle
Als Randbemerkung, Objective-C Objektreferenzen sind nicht direkt C structs Variablen, sondern eher wie ‚Zeiger auf structs‘, so dass die Punktsyntax Sinn Zugang Mitglieder nicht direkt machen würde; Es ist der Pfeiloperator ->, der diese Rolle erfüllt (natürlich immer dann, wenn die Ivars nicht auf den Zugriff beschränkt sind).
Nicolas Miari
1

Ich denke, ich könnte zu Messaging anstelle von Punktnotation wechseln, weil in meinem Kopf object.instanceVar nur instanceVar ist , das zum Objekt gehört. Für mich sieht es überhaupt nicht wie ein Methodenaufruf aus , der es ist, also könnte es Dinge geben on in Ihrem Accessor und ob Sie instanceVar oder self.instanceVar verwenden, kann einen viel größeren Unterschied haben als nur implizit oder explizit. Nur meine 2 ¢.

mk12
quelle
1

Die Punktnotation versucht, Nachrichten wie Zugriffe auf ein Mitglied einer Struktur aussehen zu lassen, was sie nicht sind. Könnte in einigen Fällen gut funktionieren. Aber bald wird sich jemand so etwas einfallen lassen:

NSView *myView = ...;
myView.frame.size.width = newWidth;

Sieht gut aus. Ist aber nicht. Es ist das gleiche wie

[myView frame].size.width = newWidth;

was nicht funktioniert. Der Compiler akzeptiert den ersten, aber zu Recht nicht den zweiten. Und selbst wenn beim ersten Mal ein Fehler oder eine Warnung ausgegeben wurde, ist dies nur verwirrend.

Sven
quelle
1

Nennen Sie mich faul, aber wenn ich ein einzelnes 'eingeben müsste.' gegen zwei [] jedes Mal, um die gleichen Ergebnisse zu erzielen, würde ich eine einzelne bevorzugen. Ich hasse ausführliche Sprachen. Das () in lisp hat mich verrückt gemacht. Elegante Sprachen wie Mathematik sind prägnant und effektiv, alle anderen sind unzureichend.

Joe
quelle
1
Das Problem ist, dass Mathematik, obwohl sie kurz und effektiv ist, keine reguläre Sprache ist und wir sie daher nicht analysieren und kompilieren können. Beachten Sie beispielsweise, dass es in mathematischen Funktionen üblich ist, sie in Klammern zu schreiben, da es viel schwieriger wäre, ohne sie zu folgen.
Jbrennan
1

Verwenden Sie die Punktnotation (wann immer Sie können)

Bei Instanzmethoden, die einen Wert zurückgeben

Verwenden Sie keine Punktnotation

Bei Instanzmethoden, die void zurückgeben, bei Init-Methoden oder bei Class-Methoden.

Und meine persönliche Lieblingsausnahme

NSMutableArray * array = @[].mutableCopy;
Nicolas Manzini
quelle
0

Ich persönlich verwende im Code überhaupt keine Punktnotation. Ich verwende es nur bei Bedarf im CoreData KVC-Bindungsausdruck.

Der Grund dafür, dass ich sie nicht im Code verwende, ist, dass die Punktnotation die Setter-Semantik verbirgt. Das Festlegen einer Eigenschaft in Punktnotation sieht unabhängig von der Setter-Semantik (Zuweisen / Beibehalten / Kopieren) immer wie eine Zuweisung aus. Die Verwendung der Nachrichtennotation macht sichtbar, dass das empfangende Objekt die Kontrolle darüber hat, was im Setter geschieht, und unterstreicht die Tatsache, dass diese Effekte berücksichtigt werden müssen.

Ich überlege immer noch, ob ich beim Abrufen des Werts einer KVC-kompatiblen oder deklarierten Eigenschaft möglicherweise die Punktnotation verwenden möchte, da diese zugegebenermaßen etwas kompakter und lesbarer ist und keine versteckte Semantik vorhanden ist. Im Moment bleibe ich aus Gründen der Konsistenz bei der Notation von Nachrichten.

VoidPointer
quelle
1
Es könnten immer noch versteckte Dinge vor sich gehen. Ein Getter kann andere Dinge tun, als nur eine Instanzvariable zurückzugeben. Selbst wenn es sich um eine deklarierte Eigenschaft handelt, muss der Getter nicht synthetisiert werden oder er könnte in einer Unterklasse überschrieben worden sein.
Sven
-1

OK, die Punktnotation in Objective-C sieht in der Tat seltsam aus. Aber ohne das kann ich immer noch nichts machen:

int width = self.frame.size.width;

Funktioniert gut, aber:

int height = [[[self frame] size] height];

Gibt mir "Kann nicht in einen Zeigertyp konvertieren". Ich möchte jedoch, dass mein Code mit der Nachrichtennotation übereinstimmt.

Vegetus '78
quelle
5
-frame gibt ein NSRect zurück, bei dem es sich um eine C-Struktur und nicht um ein Objective-C-Objekt handelt. Aus diesem Grund verursacht das zweite Beispiel einen Compilerfehler. Es sollte sein: int height = [self frame] .size.height;
1
Einverstanden. Aber der Punkt nach der Klammer sieht schrecklich aus! Normalerweise speichere ich das Rect zuerst in einer lokalen Variablen.
Nicolas Miari
-2

Dies ist eine großartige Frage, und ich sehe viele verschiedene Antworten darauf. Obwohl viele die Themen angesprochen haben, werde ich versuchen, dies aus einem anderen Blickwinkel zu beantworten (einige haben es möglicherweise implizit getan):

Wenn wir die 'Punkt'-Notation verwenden, erfolgt die Auflösung des Ziels für die Methode zur Kompilierungszeit. Wenn wir die Nachrichtenübergabe verwenden, wird die Auflösung des Ziels auf die Laufzeitausführung verschoben. Wenn die Ziele zur Kompilierungszeit aufgelöst werden, ist die Ausführung schneller, da das Auflösen der Ziele zur Laufzeit einige Overheads beinhaltet. (Nicht dass der Zeitunterschied viel ausmachen würde). Da wir die Eigenschaft bereits in der Schnittstelle des Objekts definiert haben, macht es keinen Sinn, die Auflösung des Ziels für eine Eigenschaft zur Laufzeit zu unterscheiden, und daher ist die Punktnotation die Notation, die wir für den Zugriff auf die Eigenschaft verwenden sollten.

Jas
quelle
Ist Ihnen bekannt, dass in ObjectiveC Selektoren auf jeden Fall zur Laufzeit ausgewertet, aufgelöst und aufgerufen werden? Daher ist die Punktnotation ein reines Synonym für den alten Klammerstil. Es gibt keinerlei technische Unterschiede. Ihre Geschwindigkeitsannahmen sind einfach falsch - probieren Sie es aus, verwenden Sie Instrumente und überzeugen Sie sich selbst.
Bis zum