Frage

In den meisten Beispielen sehe ich die folgende Einstellung von IBOutlets:



(Example A)

FooController.h:

@interface FooController : UIViewController {
    UILabel *fooLabel;
}

@property (nonatomic, retain) IBOutlet UILabel *fooLabel;

@end

FooController.m:

@implementation FooController

@synthesize fooLabel;

@end

Das funktioniert aber auch in Ordnung (Hinweis: kein Eigentum und keine synthesize):



(Example B)

FooController.h:

@interface FooController : UIViewController {
    IBOutlet UILabel *fooLabel;
}

@end

FooController.m:

@implementation FooController

@end

Gibt es irgendwelche Nachteile von IBOutlets wie in Beispiel B definieren? Wie Speicherlecks? Scheint gut zu funktionieren und ich ziehe die IBOutlets als öffentliche Eigenschaften nicht aussetzen, da sie nicht als solche verwendet werden, werden sie nur in der Controller-Implementierung verwendet. Definieren sie an drei Stellen ohne wirkliche Notwendigkeit mich nicht so sehr DRY schlagen (Do not Repeat Yourself).

War es hilfreich?

Lösung

Unter Mac OS X, IBOutlets werden wie folgt angeschlossen:

  1. für eine Methode namens Schauen gesetzt :. Wenn es vorhanden nennen.
  2. Wenn keine Methode existiert, suchen Sie nach einer Instanz Variable mit dem Namen , stellen Sie ohne Halt .

Auf dem iPhone OS, IBOutlets werden wie folgt angeschlossen:

  1. call [object setValue: outletValue forKey: @ ""]

Das Verhalten des Sollwertes für Schlüssel ist, um so etwas zu tun:

  1. für eine Methode namens Schauen gesetzt :. Wenn es vorhanden nennen.
  2. Wenn keine Methode existiert, suchen Sie nach einer Instanz Variable mit dem Namen , setzen Sie ihn und beibehalten es.

Wenn Sie eine Eigenschaft verwenden, werden Sie fallen in die „ Suchen Sie nach einer Methode namens set ... “ Fall auf beiden Plattformen. Wenn Sie nur eine Instanz-Variable verwenden, dann werden Sie anders haben behalten / Freisetzungsverhalten auf Mac OS X VS iPhone OS. Es ist nichts falsch mit einer Instanz Variable, die Sie gerade benötigen mit diesem Unterschied im Verhalten umgehen, wie Sie von Plattform zu Plattform wechseln.

Hier ist ein Link auf eine vollständige Dokumentation gerade diesem Thema. https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html#//apple_ref/doc/uid/10000051i-CH4-SW6

Andere Tipps

Unter Mac OS X, IBOutlets nicht durch Standardwerte beibehalten. Das ist das Gegenteil von dem Verhalten auf dem iPhone O: auf iPhone OS, wenn Sie nicht über eine Eigenschaft deklarieren es beibehalten wird, und Sie müssen diese Eigenschaft in der dealloc Methode lösen. Darüber hinaus kann die 64-Bit-Runtime-Instanzvariablen mit Eigenschaftsdeklarationen synthetisieren. Das bedeutet, dass ein Tag der Instanzvariablen (mit dem IBOutlet) weggelassen werden können.

Aus diesen Gründen ist es homogener und kompatibel immer eine Eigenschaft zu schaffen und die IBOutlet nur in der Eigenschaft verwenden. Leider ist es auch ausführlicher.

In Ihrem ersten Beispiel haben Sie immer die Steckdose in der dealloc Methode zu lösen. In Ihrem zweiten Beispiel müssen Sie den Ausgang freigeben nur mit iPhone OS.

Das Endergebnis ist genau die gleiche, aber Sie haben ein paar Dinge im Auge zu behalten:

  • Wenn Instanzfelder als Steckdosen verwenden, sollten Sie lassen Sie sie nicht in dealloc .

  • Wenn Eigenschaften mit, die das (behalten) Attribut hat, müssen Sie die Eigenschaft Release in dealloc (mit self.property=nil oder durch die Unterstützung variabler Freigabe). Dies macht es viel mehr transparent, was vor sich geht.

Eigentlich alles kommt es auf die gleiche alte Regel: „ soll mir loslassen, was Sie alloc / behalten “. Also, falls Sie eine Instanz Feld als Ausgang verwenden, Sie haben es nicht alloc / behalten, so dass Sie es nicht loslassen sollte.

Es ist möglich, dass diese Beispiele die behalten verwenden, weil der Beispielcode programmatisch zuteilt und ein UILabel initialisiert und dann auf die UIView hinzufügen. Das ist der Fall für viele Beispiele, da das Lernen, wie Interface Builder zu verwenden, ist oft nicht ihr Punkt.

Das zweite Beispiel (kein Eigentum und keine synthesize) mit dem IBOutlet verwendet wird, wenn der Entwickler ‚weist‘ die UILabel (Button, Ansicht, usw.) im Interface Builder - durch die IBOulet auf das Etikett oder andere View-Komponente ziehen . Meiner Meinung nach ist die vorhergehende Drag-and-Drop-Aktion (Etikett auf View) auch noch die Subview, das Label auf einen Blick - und so weiter. Label wird von einer Ansicht beibehalten; Eine Ansicht ist durch Fenster zurückgehalten wird; Fenster werden von Datei-Besitzer erhalten. Datei-Besitzer ist in der Regel Ihr Dokument, das in Haupt gebootet wird.

Sie werden bemerken, dass, wenn Sie Ihr Programm Schritt für Schritt durch (durch eine awakeFromNib Hinzufügen

- (void)awakeFromNib
{
    [fooLabel blahblah];
}

, dass fooLabel bereits eine Speicheradresse.

Das ist, weil das Etikett aus einer Datei Bündel (die NIB-Datei) initialisiert wurde mit nicht init aber initWithCoder. Welche deserialisiert im Wesentlichen die Filestream auf ein Objekt - und setzt dann die IBOutlet Variable. (Wir reden immer noch über die IBOutlet Methode).

Beachten Sie auch, dass die vorgenannte iOS Methode der Schlüsselwert-Methode verwendet

  call [object setValue:outletValue forKey:@"<OutletName>"]

das ist der Observer / Observable Muster. Dieses Muster erfordert den beobachtbaren Objektverweis jeden Beobachter in einem Set / Array. Eine Wertänderung wird die Set / Array iterieren und ebenso alle Beobachter aktualisieren. Das Set wird bereits jeden Beobachter behält somit den Mangel behalten von in iOS.

Weitere und der Rest ist Spekulation.

Es scheint, dass Fälle, in denen Sie Interface Builder dann verwenden

 @property (nonatomic, retain) IBOutlet UILabel *fooLabel;

möglicherweise geändert werden soll, um

@property (nonatomic, weak) IBOutlet UILabel *fooLabel;

oder     @property (nonatomic, zuweisen) IBOutlet UILabel * fooLabel;

Und dann braucht es nicht in einem dealloc Verfahren gelöst werden. Außerdem wird es die OSX und iOS Anforderungen erfüllen.

Das basiert auf Logik und ich konnte ein paar Stücke hier fehlen.

Trotzdem kann es keine Rolle, ob der Blick durch das Leben Ihres Programms persistent ist. Während ein Etiketts in einem modalen Dialogfeld (Öffnen, Schließen, Öffnen, Schließen) in der Tat kann über beibehalten und Leck pro Zyklus. Und das ist, weil (Spekulation wieder), das jeweils geschlossenes Dialogfeld in ein Dateisystem serialisiert wird und somit bleibt x, y-Position und Größe, zusammen mit seinen Subviews usw. und anschließend deserialisiert ... auf der nächsten Sitzung geöffnet (Im Gegensatz minimiz zu sagen oder versteckt).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top