574 Stimmen

Sollten IBOutlets unter ARC stark oder schwach sein?

Ich entwickle ausschließlich für iOS 5 mit ARC. Sollten IBOutlets zu UIViews (und Unterklassen) strong oder weak sein?

Das Folgende:

@property (nonatomic, weak) IBOutlet UIButton *button;

Würde das hier loswerden:

- (void)viewDidUnload
{
    // ...
    self.button = nil;
    // ...
}

Gibt es dabei irgendwelche Probleme? Die Vorlagen verwenden strong, genauso wie die automatisch generierten Eigenschaften, die erstellt werden, wenn man direkt aus dem 'Interface Builder'-Editor mit dem Header verbindet, aber warum? Der UIViewController hat bereits eine strong-Referenz zu seinem view, der seine Subviews behält.

11 Stimmen

Als Hinweis, IBOutletCollection() darf nicht weak sein, ansonsten wird es als nil zurückgegeben.

0 Stimmen

Xcode 8.2.1 verwendet weak, wenn IBOutlets über den Interface Builder erstellt werden. Viele Antworten hier auf SO raten jedoch, strong zu verwenden.

1 Stimmen

@neoneye Ich habe es gerade mit xcode 8.3.2 ausprobiert, indem ich vom Storyboard zur Swift-Datei gezogen habe, und es wird standardmäßig auf strong festgelegt.

20voto

Giuseppe Punkte 6676

Beim iOS-Entwicklung ist das Laden von NIB etwas anders als bei der Mac-Entwicklung.

In der Mac-Entwicklung ist ein IBOutlet normalerweise eine schwache Referenz: Wenn Sie eine Unterklasse von NSViewController haben, wird nur die Ansicht der obersten Ebene behalten, und wenn Sie den Controller deallokieren, werden automatisch alle seine Unteransichten und Outlets freigegeben.

UiViewController verwendet Key Value Coding, um die Outlets mit starken Referenzen zu setzen. Wenn Sie also Ihren UIViewController deallokieren, wird die oberste Ansicht automatisch deallokiert, aber Sie müssen auch alle seine Outlets in der dealloc Methode deallokieren.

In diesem Beitrag von Big Nerd Ranch wird dieses Thema behandelt und auch erklärt, warum die Verwendung einer starken Referenz in IBOutlet keine gute Wahl ist (auch wenn sie in diesem Fall von Apple empfohlen wird).

17 Stimmen

Es erklärt es wie im Jahr 2009. Mit ARC hat sich dies erheblich geändert.

1 Stimmen

:( der Link zum Big Nerd Ranch ist tot... dabei muss ich es wirklich lesen. Kennt jemand weitere Details zu diesem Beitrag, damit ich ihn finden kann?

0 Stimmen

@mottishneor Keine Sorge, es ist kein großes Problem, da der Link Zeiten vor ARC betrifft und nicht mehr relevant ist.

18voto

syedfa Punkte 2775

Etwas, das ich hier herausstellen möchte, und das ist, trotz dessen, was die Apple-Ingenieure in ihrem eigenen WWDC 2015-Video hier erklärt haben:

https://developer.apple.com/videos/play/wwdc2015/407/

Apple ändert ständig ihre Meinung zu diesem Thema, was uns zeigt, dass es keine einzige richtige Antwort auf diese Frage gibt. Um zu zeigen, dass selbst die Apple-Ingenieure in diesem Punkt geteilter Meinung sind, sollten Sie sich Apples aktuellste Beispielimplementierung ansehen, dort verwenden einige Personen weak, und einige nicht.

In diesem Apple Pay-Beispiel wird weak verwendet: https://developer.apple.com/library/ios/samplecode/Emporium/Listings/Emporium_ProductTableViewController_swift.html#//apple_ref/doc/uid/TP40016175-Emporium_ProductTableViewController_swift-DontLinkElementID_8

Genauso wie in diesem Picture-in-Picture-Beispiel: https://developer.apple.com/library/ios/samplecode/AVFoundationPiPPlayer/Listings/AVFoundationPiPPlayer_PlayerViewController_swift.html#//apple_ref/doc/uid/TP40016166-AVFoundationPiPPlayer_PlayerViewController_swift-DontLinkElementID_4

Genauso wie im Lister-Beispiel: https://developer.apple.com/library/ios/samplecode/Lister/Listings/Lister_ListCell_swift.html#//apple_ref/doc/uid/TP40014701-Lister_ListCell_swift-DontLinkElementID_57

Genauso wie im Core Location-Beispiel: https://developer.apple.com/library/ios/samplecode/PotLoc/Listings/Potloc_PotlocViewController_swift.html#//apple_ref/doc/uid/TP40016176-Potloc_PotlocViewController_swift-DontLinkElementID_6

Genauso wie im View Controller-Beispiel für die Vorschau: https://developer.apple.com/library/ios/samplecode/ViewControllerPreviews/Listings/Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift.html#//apple_ref/doc/uid/TP40016546-Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift-DontLinkElementID_5

Genauso wie im HomeKit-Beispiel: https://developer.apple.com/library/ios/samplecode/HomeKitCatalog/Listings/HMCatalog_Homes_Action_Sets_ActionSetViewController_swift.html#//apple_ref/doc/uid/TP40015048-HMCatalog_Homes_Action_Sets_ActionSetViewController_swift-DontLinkElementID_23

All dies ist vollständig aktualisiert für iOS 9 und alle verwenden weak outlets. Dadurch lernen wir, dass A. Das Problem nicht so einfach ist, wie es manche Leute beschreiben. B. Apple hat wiederholt seine Meinung geändert, und C. Sie können verwenden, was Ihnen gefällt :)

Ein besonderer Dank geht an Paul Hudson (Autor von www.hackingwithsift.com), der mir die Klärung und Verweise für diese Antwort gegeben hat.

Hoffentlich verdeutlicht das Thema etwas besser!

Pass auf dich auf.

0 Stimmen

Ich habe dieses Problem seit einiger Zeit überprüft und bislang keine konkreten Antworten gefunden. Da der obige Link nahelegt, dass beide in Ordnung sind und im Allgemeinen das verwenden, was Xcode vorschlägt.

10voto

Johannes Punkte 11026

Von der WWDC 2015 gibt es eine Sitzung über Implementierung von UI-Designs in Interface Builder. Um den 32-Minuten-Markierung sagt er, dass Sie immer Ihr @IBOutlet stark machen möchten.

0 Stimmen

Interessant. Ich nehme an, dass sich dies geändert hat, als das Ansichtsentladen entfernt wurde?

6voto

landonandrey Punkte 1161

Bitte beachten Sie, dass IBOutletCollection @property (strong, nonatomic) sein sollte.

3 Stimmen

Warum nicht copy als es ist ein NSArray?

5voto

Julian Punkte 9109

Es scheint, dass sich im Laufe der Jahre etwas verändert hat und Apple jetzt im Allgemeinen empfiehlt, in der Regel stark zu verwenden. Der Beweis für ihre WWDC-Sitzung befindet sich unter Sitzung 407 - Implementierung von UI-Designs in Interface Builder und beginnt um 32:30. Meine Notiz von dem, was er sagt, ist (fast, wenn nicht genau, zitiere ihn):

  • Outlet-Verbindungen sollten im Allgemeinen stark sein, insbesondere wenn wir eine Subview oder Einschränkung verbinden, die nicht immer von der Ansichtshierarchie zurückgehalten wird

  • Schwache Outlet-Verbindung könnte erforderlich sein, wenn benutzerdefinierte Ansichten erstellt werden, die einen Verweis auf etwas in der Ansichtshierarchie haben, und im Allgemeinen wird dies nicht empfohlen

Anders ausgedrückt sollte es jetzt immer stark sein, solange unsere benutzerdefinierte Ansicht keinen Zyklus mit einigen Ansichten in der Ansichtshierarchie erstellt

BEARBEITEN:

Einige mögen die Frage stellen. Verursacht das Halten einer starken Referenz keinen Zyklus, da der Stamm-Ansichtscontroller und die besitzende Ansicht die Referenz dazu behalten? Oder warum hat sich das geändert? Ich glaube, die Antwort findet sich früher in diesem Vortrag, als sie beschreiben, wie die xibs aus dem xib erstellt werden. Es wird ein separates xib für einen VC und für die Ansicht erstellt. Ich glaube, das könnte der Grund sein, warum sie die Empfehlungen geändert haben. Es wäre jedoch schön, eine tiefere Erklärung von Apple zu erhalten.

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