6 Stimmen

Bedingt IBOutlet __weak?

Ich fange gerade mit ARC an. Vor ARC habe ich meine Outlets einfach so deklariert, zum Beispiel: IBOutlet UIButton *button;, also ohne es zu behalten oder ähnliches. Mit ARC impliziert das Nichtspezifizieren von weak oder strong stark.

Also, wenn ich unter ARC dasselbe tue (d.h. IBOutlet UIButton *button;), bedeutet das, dass button eine starke Referenz ist? oder muss ich es explizit als weak definieren?

Kurz gesagt, impliziert IBOutlet __weak?

16voto

jscs Punkte 63009

Das Wort IBOutlet ist tatsächlich als nichts definiert:

#define IBOutlet

Xcode verwendet einfach das Vorhandensein dieses Wortes in Ihrem Code, um Ihnen das Herstellen von Verbindungen im Interface Builder zu ermöglichen. Eine Deklaration einer Variablen oder einer Eigenschaft als IBOutlet:

IBOutlet UIButton * button;
@property (...) IBOutlet UIButton * button;

hat daher keine direkte Auswirkung, was ARC betrifft; es übersetzt nicht (obwohl es theoretisch könnte) in __weak oder ähnliches. Das Wort selbst ist vollständig aus Ihrem Quellcode verschwunden, wenn der Compiler ihn erhält.

Andererseits hat die Tatsache, dass diese Variable oder Eigenschaft ein Outlet ist, einen bedeutsamen Einfluss darauf, wie Sie über das Speichermanagement nachdenken müssen.

Der implizite Speicherqualifizierer für eine Objektvariablendeklaration wie IBOutlet UIButton * button; unter ARC ist __strong, wie Sie sagten - jedes Objekt, das der Variablen zugewiesen wird, wird als "besessen" betrachtet. Unter MRR ist die Deklaration lediglich ein Zeiger; eine Zuweisung hat keine Auswirkung auf den Referenzzähler/Besitz des zugeordneten Objekts - sie verhält sich genauso wie eine assign Eigenschaft.* Daher ändert sich die Bedeutung derselben ivar-Deklaration zwischen den beiden Verwaltungssystemen.

Objekte in einem xib haben Besitzereigentumsbeziehungen, die durch die Ansichtshierarchie gebildet werden; das heißt, Elternansichten besitzen ihre Untergeordneten. Die Top-Level-Ansicht in einem xib gehört dem Objekt, das als Dateibesitzer bekannt ist. Diese Einrichtung bedeutet, dass Ihre Verbindungen zu Objekten in einem xib, die nicht Top-Level sind, (unter ARC) weak oder (als Eigenschaft unter MRR) assign sein sollte. Es handelt sich nicht um Besitzverhältnisse; sie sind im Wesentlichen bequeme Indizes in die Ansichtsliste. Dies ist die Empfehlung von Apple:

...Sie müssen keine starken Verweise auf Objekte weiter unten im Diagramm haben, da sie vom Elternobjekt besessen sind, und Sie sollten das Risiko der Schaffung starker Verweiszyklen minimieren.

[...]Verbindungen sollten im Allgemeinen weak sein, außer für solche vom Dateibesitzer zu Top-Level-Objekten in einer Schnipsel-Datei (oder, in iOS, einer Storyboard-Szene), die strong sein sollten. Verbindungen, die Sie erstellen, sollten daher standardmäßig weak sein...

Ihre einfachen Zeiger IBOutlets, wie ich erklärt habe, haben - für Speichermanagementzwecke - wie weak Eigenschaften gehandelt,** was bedeutet, dass sie das Richtige getan haben. Die gleiche Deklaration wird wahrscheinlich zum falschen Ergebnis führen, wenn sie unter ARC kompiliert wird.

Zusammenfassend: IBOutlet übersetzt nicht zu weak, ändert jedoch die Bedeutung des Zeigers. Da die Standard-Speicherverwaltungssemantik von IBOutlet UIButton * button; von "assign" unter MRR zu "besessen" unter ARC wechselt und da IBOutlets im Allgemeinen nicht besitzend sein sollten, impliziert das Vorhandensein von IBOutlet tatsächlich, dass der Zeiger unter ARC als __weak deklariert werden sollte.†


*Und ähnlich wie bei einer weak Eigenschaft - der einzige Unterschied besteht darin, dass weak Zeiger auf nil gesetzt werden, wenn das Objekt deallokiert wird.

**Außer dem automatischen nil Teil.

†Oder, wirklich, sollte es eine weak Eigenschaft sein.

4voto

Pochi Punkte 13352

Nein, IBOutlet wird im Wesentlichen gestrippt, wenn der Code kompiliert wird. Es ist jedoch ein Helfer für XCode, damit es weiß, WAS ein InterfaceBuilderOutlet ist.

Im Grunde genommen erlaubt dieses Wort, ein Element im Interface Builder zu verbinden.

Standardmäßig wird es trotzdem stark sein (stellen Sie sich einfach vor, dass das Wort nicht da ist).

Es wird jedoch empfohlen, es auf schwach zu setzen, weil sobald etwas mit dem Interface Builder verbunden ist, hält DAS Interface eine starke Referenz dazu, daher ist es sinnlos, eine doppelte starke Referenz zu haben, insbesondere wenn dieses Element nicht lebendig gehalten werden soll, wenn das Interface entladen wurde.

Lesen Sie diese Frage, die genau das ist, wonach Sie suchen:

Sollten IBOutlets unter ARC stark oder schwach sein?

3voto

bbarnhart Punkte 6460

Das IBOutlet-Schlüsselwort wird nur verwendet, um das Objekt mit einem Element in Interface Builder zu verknüpfen. Es hat nichts mit schwach oder stark oder ARC oder Speicherverwaltung zu tun.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X