Eigenschaften unter ARC: Immer oder nur öffentlich?

9

Nachdem ich vor etwas weniger als zwei Jahren einen Artikel mit dem demütigen Titel "Die Code-Gebote: Best Practices für die Objective-C-Codierung" von Robert McNally gelesen hatte, übernahm ich die Praxis, Eigenschaften für so ziemlich jedes Datenelement meiner Objective-C-Klassen zu verwenden ( das 3. Gebot ab Mai 2012). McNally listet diese Gründe dafür auf (meine Betonung):

  1. Eigenschaften erzwingen Zugriffsbeschränkungen (z. B. schreibgeschützt)
  2. Eigenschaften erzwingen die Speicherverwaltungsrichtlinie (stark, schwach)
  3. Eigenschaften bieten die Möglichkeit, benutzerdefinierte Setter und Getter transparent zu implementieren.
  4. Eigenschaften mit benutzerdefinierten Setzern oder Gettern können verwendet werden, um eine Thread-Sicherheitsstrategie durchzusetzen.
  5. Ein einziger Zugriff auf Instanzvariablen erhöht die Lesbarkeit des Codes.

Ich habe die meisten meiner Immobilien in private Kategorien eingeteilt, daher sind Nummer 1 und 4 normalerweise keine Probleme, auf die ich stoße. Die Argumente 3 und 5 sind eher "weich", und mit den richtigen Tools und anderen Konsistenzen könnten sie zu Problemen werden. Schließlich war für mich das einflussreichste dieser Argumente Nummer 2, die Speicherverwaltung. Ich mache das seitdem.

@property (nonatomic, strong) id object; // Properties became my friends.

Bei meinen letzten Projekten habe ich auf ARC umgestellt, was mich bezweifeln ließ, ob das Erstellen von Eigenschaften für so ziemlich alles noch eine gute Idee oder vielleicht ein wenig überflüssig ist. ARC kümmert sich für mich um die Speicherverwaltung von Objective-C-Objekten, was für die meisten strongMitglieder gut funktioniert, wenn Sie nur die ivars deklarieren. Die C-Typen, die Sie ohnehin vor und nach ARC manuell verwalten mussten, und die weakEigenschaften sind meist öffentliche.

Natürlich verwende ich immer noch Eigenschaften für alles, was Zugriff von außerhalb der Klasse benötigt, aber dies sind meist nur eine Handvoll Eigenschaften, während die meisten Datenelemente als ivars unter dem Implementierungsheader aufgeführt sind

@implementation GTWeekViewController
{
    UILongPressGestureRecognizer *_pressRecognizer;
    GTPagingGestureRecognizer *_pagingRecognizer;
    UITapGestureRecognizer *_tapRecognizer;
}

Als Experiment habe ich dies etwas strenger gemacht, und die Abkehr von den Eigenschaften für alles hat einige nette positive Nebenwirkungen.

  1. Die Anforderungen an den Datenelementcode ( @property/ @synthesize) wurden auf die ivar-Deklaration reduziert.
  2. Die meisten meiner self.somethingReferenzen wurden gerade aufgeräumt _something.
  3. Es ist leicht zu unterscheiden, welche Datenelemente privat (ivars) und welche öffentlich (Eigenschaften) sind.
  4. Schließlich fühlt es sich eher so an, als wäre dies der Zweck, für den Apple Eigenschaften vorgesehen hat, aber das ist subjektive Spekulation.

Weiter zur Frage : Ich rutsche langsam auf die dunkle Seite zu und verwende immer weniger Eigenschaften zugunsten von Implementierungs-Ivars. Können Sie mir ein paar Gründe nennen, warum ich bei der Verwendung von Eigenschaften für alles bleiben sollte, oder meinen aktuellen Gedankengang bestätigen, warum ich nur bei Bedarf mehr Ivars und weniger Eigenschaften verwenden sollte? Die überzeugendste Antwort für beide Seiten wird meine Note erhalten.

EDIT: McNally wiegt sich auf Twitter ein und sagt : "Ich denke, mein Hauptgrund für das Festhalten an Eigenschaften ist: Eine Möglichkeit, alles zu tun, die alles tut (einschließlich KVC / KVO)."

Epologe
quelle

Antworten:

5

Können Sie mir ein paar Gründe nennen, warum ich bei der Verwendung von Eigenschaften für alles bleiben sollte, oder meine aktuellen Überlegungen bestätigen, warum ich nur bei Bedarf mehr Ivars und weniger Eigenschaften verwenden sollte?

Im Moment denke ich, dass es fair ist zu sagen, dass es hauptsächlich eine Frage des Stils ist. Wie Sie sagen, ist der Speicherverwaltungsvorteil von Eigenschaften bei ARC weniger wichtig. Andererseits sind die "Vorteile" der Rückkehr zum direkten Ivar-Zugang auch nicht sehr überzeugend:

  1. Eine @ property-Deklaration ist einer ivar-Deklaration ziemlich ähnlich. Das Vermeiden der @synthesize-Direktive scheint kein großer Gewinn zu sein - wir sprechen nicht über viel Code.

  2. Die foo.somethingSyntax ist wohl viel besser als _something. Die Eigenschaftszugriffssyntax sieht offensichtlich so aus und funktioniert wie die Punktsyntax von C für den Zugriff auf Elemente einer Struktur. Es selfist hilfreich, explizit anzugeben, auf welches Objekt Sie zugreifen (ob dies oder etwas anderes ist). (Einige Leute - nicht ich! - befürworten self->somethingaus diesem Grund den Zugang zu Ivar.) Die führende Unterstreichungskonvention für Ivar ist in Ordnung, wird jedoch nicht von allen Objective-C-Codes konsistent verwendet.

  3. Eigenschaften scheinen eine bessere Wahl für den Zugriff auf Daten zu sein, die in anderen Objekten derselben Klasse gespeichert sind (was unter "privatem" Zugriff zulässig ist) und für den Zugriff durch Unterklassen (wie "geschützt" von C ++). Die Idee 'properties == public' ist also etwas verschwommen.

  4. Meiner Meinung nach sollten Eigenschaften die Speicherverwaltung vereinfachen und einige andere Vorteile bieten. Wie Sie sagen, scheinen die Eigenschaften mit abnehmendem Speicherverwaltungsvorteil weniger überzeugend zu sein.

Der von Ihnen gewählte Weg - zurück zum direkten ivar-Zugriff auf interne Daten - scheint eine sehr vernünftige Wahl zu sein, und es gibt keinen offensichtlichen Grund, Ihren Kurs zu ändern. Das Festhalten an Eigenschaften ist jedoch auch vernünftig - die Nachteile sind nicht wesentlich, und es gibt einige nette Vorteile wie die KVO-Konformität und einen konsistenteren Zugriffsstil für Mitglieder.

Eigenschaften waren nicht der letzte Schritt in der Entwicklung von Objective-C, und ich erwarte auch nicht, dass ARC dies sein wird. Ich habe keine spezifischen Informationen, aber es scheint eine gute Vermutung zu sein, dass irgendwann zusätzliche Funktionen hinzugefügt werden, die Eigenschaften entweder überzeugender oder weniger überzeugend machen. Wir müssen abwarten, was passiert.

Caleb
quelle
1
Hallo @Caleb, danke, dass du dir die Zeit genommen und einen soliden Beitrag geschrieben hast. Ich hatte nicht an den KVO-Aspekt gedacht. Ich bin in der Tat sehr gespannt, wohin Apple das alles führt. ARC fühlt sich wie einer in einer Reihe von Schritten an. Ich werde abwarten, ob sich jemand anderes mit dem Thema befasst. Andernfalls sollten Sie die markierte Frage prüfen.
Epologee
1
@epologee Gerne helfen. Ein weiteres Element, das der Plus-Spalte für Ivars hinzugefügt werden muss, ist, dass Sie sie im Debugger leicht sehen können. Dies gilt auch für Eigenschaften, wenn Sie den von der Eigenschaft verwendeten ivar explizit deklariert haben. Synthetisierte Ivars werden im Debugger nicht angezeigt. (Ich wäre nicht überrascht, diese Änderung eines Tages bald zu sehen.)
Caleb
-1

Ich habe auch über diese Frage nachgedacht. Meiner bescheidenen Meinung nach macht die Verwendung von Eigenschaften nur für Accessoren den Code viel lesbarer. Sie können sofort sehen, auf welche Variablen öffentlich zugegriffen werden soll. Und persönlich ist es zeitaufwändig, immer @property (...) vor einer Variablen einzugeben.

Alex Boudreau
quelle
Hallo Alex, ich denke, du bist besser dran, wenn du neuere Fragen hier auf SE beantwortest. Ich stimme dem zeitaufwändigen Argument nicht sehr zu. Ich schreibe keinen Code, der mir Zeit beim Schreiben spart. Ich schreibe gerne Code, der meinem zukünftigen Selbst oder jemand anderem Zeit spart, ihn zu verstehen. Das heißt, die -1 Stimme war nicht meine. Wäre schön für diese Person, um die Abstimmung zu klären.
Epologee