11 Stimmen

Wenn Sie ein IBOutlet, aber keine Eigenschaft haben, wird es beibehalten oder nicht?

Ich halte die Dokumentation zu diesem Thema für unklar:

Nehmen wir an, Sie arbeiten mit iOS (NICHT der Mac-Fall, die Unterschiede müssen nicht erwähnt werden). Nehmen wir an, es handelt sich ausschließlich um 4.0+ (Unterschiede im alten Betriebssystem müssen nicht erwähnt werden). Angenommen, wir laden die NIB ausschließlich automatisch.

Angenommen, Sie haben einen UIViewController, BigView. Sagen wir, es gibt ein Dutzend sogenannter "Top-Level"-Elemente in der NIB-Datei... das können benutzerdefinierte Steuerelemente, Bilder oder etwas anderes sein.

Nehmen wir an, Sie wollen BigView explizit erstellen und dann mehrmals während der Laufzeit der Anwendung wieder loswerden. Also:

Für einen dieser Top-Level-Elemente in der NIB gibt es drei Möglichkeiten :

(1) Sie haben keinerlei IBOutlet dafür.

(2) Sie haben ein verbundenes IBOutlet - aber keine Eigenschaft.

(3) Sie haben eine verknüpfte IBOutlet-Eigenschaft (um Verwirrung zu vermeiden, sagen wir eine Retain-Eigenschaft).

Was passiert also mit dem Gegenstand, wenn BigView freigegeben wird?

Im Fall von (3) scheint es klar zu sein, dass Sie ausdrücklich freigeben müssen. Wenn Sie das nicht tun, bleibt die Funktion bestehen, nachdem die Ansicht verschwunden ist. Kein Problem.

Im Fall von (1) Ich nehme an ( aber kann das jemand bestätigen? ), dass der Artikel freigegeben wird, wenn BigView nicht mehr verfügbar ist.

Im Fall von (2) Es ist nicht klar, was passiert.......

Ein Blick auf den bekannten Referenzlink: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html ist das sehr zweifelhaft:

"In iOS verwendet der Code zum Laden der Feder die Methode setValue:forKey:, um jeden Ausgang wieder anzuschließen. Diese Methode sucht ebenfalls nach einer geeigneten Accessor-Methode und [SO WHAT HAPPENS IF THERE ISN'T ONE?? TELL US APPLE...] greift auf andere Mittel zurück, wenn das fehlschlägt...[GOOD GRIEF!]"

Und scrollen Sie nach unten zu "Nib Object Retention":

"Objekte in der Nib-Datei werden mit einem Retain Count von 1 erstellt und dann automatisch wieder freigegeben" Fantastisch.

Doch halt! Lesen Sie ein paar Worte weiter...

der jedoch die verfügbare Setter-Methode verwendet oder das Objekt standardmäßig beibehält, wenn keine Setter-Methode verfügbar ist

Wovon reden sie?

Bedeutet dies, dass, wenn kein Setter verfügbar ist (ivar, aber keine Eigenschaft), es sich um AGAIN RETAINED (anders als das "retain", das sie gerade in der vorherigen Klausel erwähnen) --- oder wiederholen sie sich nur, d.h. das "retains the object by default" ist das gleiche "retain", von dem sie unmittelbar zuvor sprachen ("created with a retain count of 1 and then autoreleased").

Und warum sollten sie die automatische Freigabe überhaupt erwähnen, wenn das nicht der Fall ist?

In der Tat - falls jemand die Antwort auf diese Frage konkret kennt ...... Woher weißt du das?!? Haben Sie DTS gefragt, oder durch Tests, oder? Ich schlage vor, die Schlüsseldokumentation (gerade eingefügt) ist äußerst unklar.

Auch hier gilt: Wenn Sie ein IBOutlet, aber nicht eine Eigenschaft , verbunden mit einem "Top-Level" Objekt .. sind Sie für die Freigabe verantwortlich? Wird es einbehalten? in dieser Situation?

Im Übrigen .... nur in Situation (1) ist es absolut der Fall, dass das Ding freigegeben wird, wenn BigView verschwindet? Ich würde davon ausgehen, dass dies der Fall ist, aber wer weiß?

Die Frage ist, was passiert, wenn Sie ein IBOutlet iVar verwenden, aber NICHT eine Eigenschaft...

Ich habe dummerweise noch nie darüber nachgedacht / zu viel vermutet, hat jemand die entscheidende Antwort? Prost!!


Für das Protokoll habe ich ein Testprojekt erstellt.

In der Tat (für mich überraschend) der bloße Akt des Verbindens eines IB-Elements mit einem IBOutlet fügt in der Tat anscheinend ein weiteres Element hinzu .

(Ich kann nur vermuten, aus der schlampigen Doku, in dieser Situation bekommen Sie speziell: Retain, Autorelease, Retain - was unterm Strich zu einem Retain führt).

So, das ist die Antwort.

Ich werde das Demoprojekt veröffentlichen. Ich verweise auch alle Leser auf Jonahs Antwort unten, die das Verhalten von setValue:forKey einwandfrei erklärt: Vielen Dank

0 Stimmen

Vielen Dank. Ich habe mir GENAU die gleichen Fragen gestellt! Ich war so verwirrt, nachdem ich die Apple-Dokumente gelesen hatte, dass ich völlig unsicher war, woran ich glauben sollte. Und auch Dank an Jonah für diese Klärung.

0 Stimmen

Das ist schon seltsam, da stimme ich Ihnen zu. Danke für das Up-Vote, denn das hat mir die "Super-Wesen-Macht" oder so auf dieser Seite gegeben!!! Ich bin der König der Welt!!!

11voto

Jonah Punkte 17757

Ich verstehe nicht, was so viel Verwirrung stiftet, ich denke, die Dokumentation "Nib Object Retention" erklärt genau, was passiert. Lassen Sie uns das Ganze aufschlüsseln und durchgehen, was passiert:

Die Objekte in der Nib-Datei werden mit einer Beibehaltungszahl von 1 erstellt und dann automatisch wieder freigegeben.

ClassLoadedFromNib *loadedObject = [[[ClassLoadedFromNib alloc] initWithCoder:coder] autorelease];

Beim Neuaufbau der Objekthierarchie stellt UIKit jedoch die Verbindungen zwischen den Objekten mithilfe der Methode setValue:forKey: wieder her,

[filesOwner setValue:loadedObject forKey:nameOfIBOutlet];

die die verfügbare Setter-Methode verwendet oder das Objekt standardmäßig beibehält, wenn keine Setter-Methode verfügbar ist.

Das Standardverhalten von -setValue:forKey: in iOS ist ungefähr

//lazy pseudocode
if ([self respondsToSelector:@selector(@"setKeyName:")]) {
  [self setKeyName:value];
}
else {
  object_setIvar(self, _keyName, [value retain]);
}

Weitere Einzelheiten finden Sie im Leitfaden zur Schlüsselwertprogrammierung. Sofern das Owner-Objekt Ihrer Datei nicht die -setValue:forKey: (oder +accessInstanceVariablesDirectly y -setValue:forUndefinedKey: ) erwarten, dass der Besitz von Objekten wie oben beschrieben verwaltet wird.


Wenn Sie Ausgänge für Nib-Datei-Objekte definieren, sollten Sie immer eine Setter-Methode (oder eine deklarierte Eigenschaft) für den Zugriff auf diesen Ausgang definieren. Setter-Methoden für Ausgänge sollten ihre Werte beibehalten, und Setter-Methoden für Ausgänge, die Objekte der obersten Ebene enthalten, müssen ihre Werte beibehalten, um zu verhindern, dass sie deallokiert werden.

Es ist verwirrend, wenn das Laden von Federn erlaubt wird, um ivar direkt auf extern beibehaltene Objekte zu setzen. Tun Sie das nicht. Bieten Sie Setter-Methoden für Ihre Outlets an, damit der Besitz des geladenen Objekts klar ist.


Wenn Sie die Top-Level-Objekte nicht in Outlets speichern, müssen Sie entweder das Array, das von der Methode loadNibNamed:owner:options: zurückgegeben wird, oder die Objekte innerhalb des Arrays aufbewahren, um zu verhindern, dass diese Objekte vorzeitig freigegeben werden.

Objekte, die nicht mit Steckdosen verbunden sind, wurden automatisch freigegeben. Behalten Sie sie oder das von -loadNibNamed:owner:options: zurückgegebene Array, wenn Sie später auf sie zugreifen wollen.

2voto

Caleb Punkte 121906

Es ist eine interessante Frage, aber da die Dokumentation nicht eindeutig ist, denke ich, dass der beste Plan (und derjenige, der meiner Meinung nach von Apple empfohlen wird) darin besteht, dass alle Ihre Ausgänge Eigenschaften beibehalten. Sie wissen genau, was in diesem Fall passiert, und es gibt wenig Grund, etwas anderes zu tun.

0voto

hoha Punkte 4398

Fall 1) Wenn das Objekt durch nichts zurückgehalten wird, wird es bei der nächsten Entleerung des Autorelease-Pools wieder freigegeben.

Fall 2) In der oben erwähnten Antwort hat Jon Hess bereits (mit Verweis auf die Dokumentation) die Unterschiede zwischen Mac OS X und iOS für diesen Fall beschrieben.

Ist Jon Hess korrekt oder ist Freeman korrekt?

Im Fall von iOS sagen sowohl Hess als auch Freeman, dass der Gegenstand beibehalten wird. Diesbezüglich gibt es keinen Widerspruch zwischen ihnen.

Es wird nach wie vor dringend empfohlen, für alle Ausgänge Setter-Methoden zu verwenden:

Ressource Programmierhandbuch, Nib-Dateien

Wenn Sie Ausgänge für nib-file definieren Objekte definieren, sollten Sie immer eine Setter-Methode (oder deklarierte Eigenschaft) für den Zugriff auf diesen Ausgang definieren. Setzer Methoden für Ausgänge sollten ihre ihre Werte behalten...

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