Warum ist addSubview: die Ansicht nicht beibehalten?

7

Ich füge meiner Ansicht zwei Unteransichten hinzu, die nach Eigenschaften gespeichert sind. Beim Hinzufügen der Unteransichten zu meiner Ansicht werden die Unteransichten scheinbar freigegeben, nachdem meine setup -Methode aufgerufen wurde. Das Endergebnis ist, dass die Ansichten nie angezeigt werden. Wenn ich nun meine Eigenschaften in strong im Gegensatz zu weak ändere, behalte ich einen Verweis auf die Ansichten und sie werden jetzt auf dem Bildschirm angezeigt. Also, was ist hier los? Warum behalten die addSubview: und insertSubview: die Subviews nicht bei? Siehe den folgenden Code:

Übrigens, ich benutze iOS5 mit ARC (daher das starke und schwache Zeug)

%Vor%     
Jake Vizzoni 17.03.2012, 03:32
quelle

3 Antworten

21

Hier ist eine Zeile Ihres Codes:

%Vor%

Erinnern Sie sich daran, dass die Eigenschaft horizontalLineView schwach ist. Lassen Sie uns durchgehen, was wirklich in dieser Zeile passiert, mit dem zusätzlichen Code, den ARC generiert. Zuerst senden Sie die Methoden alloc und initWithFrame: und erhalten eine starke Referenz:

%Vor%

An diesem Punkt hat das HorizontalLineView -Objekt eine Retain-Anzahl von 1. Als Nächstes, da Sie die horizontalLineView -Eigenschaft mithilfe der Punktsyntax gesetzt haben, generiert der Compiler Code, um die setHorizontalLineView: -Methode an self zu senden. Übergeben von temp als Parameter. Da die Eigenschaft HorizontalLineView für weak deklariert ist, führt die Setter-Methode Folgendes aus:

%Vor%

Das setzt self->_horizontalLineView auf temp und setzt &self->_horizontalLineView auf die Liste der schwachen Referenzen des Objekts. Aber es nicht erhöht die Retain-Anzahl des HorizontalLineView -Objekts.

Schließlich, weil die Variable temp nicht mehr benötigt wird, generiert der Compiler dies:

%Vor%

Dadurch wird die Retain-Anzahl von HorizontalLineView auf Null verringert, sodass das Objekt aufgehoben wird. Während der Aufhebung der Zuordnung wird die Liste der schwachen Referenzen durchsucht und auf nil festgelegt. So wird self->_horizontalLineView zu nil .

Um dies zu beheben, müssen Sie die Variable temp explizit machen, so dass Sie ihre Lebensdauer verlängern können, nachdem Sie das Objekt HorizontalLineView zu seiner Superansicht hinzugefügt haben, die es enthält:

%Vor%     
rob mayoff 17.03.2012, 05:08
quelle
3

Schwach sollte nicht verwendet werden, außer in Fällen, in denen ein Eltern-Kind-Retain-Zyklus gebildet wird (der Elternteil behält einen Verweis auf das Kind, das Kind behält einen Verweis auf den Elternteil, also wird auch keiner entalloct). Strong ist das ARC-Äquivalent von retain (jetzt unter ARC ungültig) und behält einen schönen stabilen Zeiger auf das Objekt für einen viel längeren Zeitraum als eine schwache Referenz, daher funktioniert addSubview tatsächlich, anstatt Ihnen irgendeine Art von Fehler zu geben.

  

Warum enthält addSubview: und insertSubview keine Unteransichten?

Haben Sie jemals versucht, auf ein Nullobjekt zu verweisen? Ja, immer noch nicht. Ihre schwache Referenz hält das UIView-Objekt nicht lange genug umher, um erfolgreich auf dem Objekt "callet" aufzurufen.

    
CodaFi 17.03.2012 04:14
quelle
0

Versuchen Sie es stattdessen:

%Vor%     
Patrick T Nelson 17.03.2012 04:19
quelle