Lazy Loading in Objective-C - Soll ich den Setter aus dem Getter herausrufen?

8

Das ist ein kleines Detail, aber jedes Mal, wenn ich faul lade, werde ich davon abgefangen. Sind beide Methoden akzeptabel? Ist entweder besser? Angenommen, die Variable hat die Eigenschaft retain.

Methode # 1

%Vor%

Methode # 2

%Vor%

Erstens bin ich mir nicht sicher, ob es OK ist, auf eine andere Accessor-Funktion innerhalb eines Accessors zuzugreifen (sehe aber nicht, warum nicht). Aber es scheint so, als ob das Setzen der Klassenvariablen ohne Durchlaufen des Settors genauso schlecht wäre, wenn der Setter etwas Spezielles tut (oder wenn die Eigenschaft zu etwas anderem als retain geändert wird und der Getter nicht überprüft wird).

    
blindjesse 14.09.2010, 19:37
quelle

4 Antworten

17

Beide sind ziemlich zerbrechlich und überhaupt nicht identisch, je nachdem, was die Kunden der Klasse machen. Es ist einfach, sie identisch zu machen - siehe unten - aber es ist schwieriger, es weniger anfällig zu machen. Dies ist der Preis für die Lazy-Initialisierung (und deshalb versuche ich im Allgemeinen, eine faule Initialisierung auf diese Weise zu vermeiden, wobei ich es vorziehe, die Initialisierung von Subsystemen als Teil der gesamten Anwendungszustandsverwaltung zu behandeln).

Mit # 1 vermeiden Sie den Setter und somit wird alles, was die Änderung beobachtet, die Änderung nicht sehen. Mit "beobachten" beziehe ich mich insbesondere auf die Schlüsselwertbeobachtung (einschließlich Cocoa Bindings, die KVO verwendet, um die Benutzeroberfläche automatisch zu aktualisieren).

Mit # 2 lösen Sie die Änderungsbenachrichtigung aus, aktualisieren die Benutzeroberfläche und ansonsten genau so, als ob der Setter aufgerufen wurde.

In beiden Fällen haben Sie das Potenzial für eine unendliche Rekursion, wenn die Initialisierung des Objekts den Getter aufruft. Dies schließt ein, wenn ein Beobachter den alten Wert als Teil der Änderungsbenachrichtigung anfordert. Mach das nicht.

Wenn Sie eine der Methoden anwenden, sollten Sie die Konsequenzen sorgfältig abwägen. Man hat das Potenzial, die App in einem inkonsistenten Zustand zu belassen, weil eine Zustandsänderung einer Eigenschaft nicht gemeldet wurde und die andere möglicherweise ein Deadlock aufweist.

Besser das Problem vollständig zu vermeiden. Siehe unten.

Überlegen Sie (Garbage Collection on, Standard-Cocoa-Kommandozeilenwerkzeug:

%Vor%

Das hängt nicht. Es spuckt aus:

%Vor%

Wenn Sie NSKeyValueObservingOptionOld zur Liste der Beobachtungsoptionen hinzufügen wollten, hängt es sehr stark.

Zurück zu einem Kommentar, den ich früher gemacht habe; Die beste Lösung besteht darin, keine faule Initialisierung als Teil Ihres Getter / Setter zu verwenden . Es ist zu feinkörnig. Sie sind viel besser dran, Ihren Objektgraphenzustand auf einer höheren Ebene zu managen und als Teil davon einen Zustandsübergang zu haben, der im Grunde von "Yo! Ich werde jetzt dieses Subsystem benutzen! Wärmen Sie diesen bösen Jungen! " das macht die faule Initialisierung.

    
bbum 14.09.2010, 19:50
quelle
3

Diese Methoden sind niemals identisch. Der erste ist richtig, während der zweite falsch ist! Ein Getter darf niemals will/didChangeValueForKey: aufrufen und daher auch nicht den Setter. Dies führt zu einer unendlichen Rekursion, wenn diese Eigenschaft beobachtet wird.

Und außerdem gibt es keine Zustandsänderung, die beobachtet werden muss, wenn das Element initialisiert wird. Sie fragen Ihr Objekt nach dem theObject und Sie bekommen es. Wenn dies erstellt wird, ist ein Implementierungsdetail und keine Sorge für die Außenwelt.

    
Sven 15.09.2010 13:01
quelle
1

Wenn Sie wissen, dass die Property-Setter-Methode ein Standard-Setter-Setter ist, sind sie identisch. Wenn nicht, müssen Sie entscheiden, ob das andere Verhalten des Setter während dieses Vorgangs aufgerufen werden soll. Wenn Sie nicht wissen, ist es am sichersten, den Setter zu verwenden, da sein Verhalten wichtig sein kann. Schwitz es nicht.

    
David M. 14.09.2010 19:48
quelle
0

Beide sind im Grunde genommen identisch, es liegt wirklich an Ihnen, zu entscheiden, welches für Ihren Fall am besten ist. Sie haben bereits die Vor- / Nachteile der Verwendung der Eigenschaftensyntax beschrieben.

    
Joshua Weinberg 14.09.2010 19:44
quelle