Ich entwickle ausschließlich für iOS 5 mit ARC. Sollte IBOutlet
s bis UIView
s (und Unterklassen) sein strong
oder weak
?
Folgende:
@property (nonatomic, weak) IBOutlet UIButton *button;
Würde all das loswerden:
- (void)viewDidUnload
{
// ...
self.button = nil;
// ...
}
Gibt es dabei Probleme? Die Vorlagen werden ebenso verwendet strong
wie die automatisch generierten Eigenschaften, die beim direkten Herstellen einer Verbindung zum Header aus dem Editor "Interface Builder" erstellt werden. Aber warum? Das hat UIViewController
bereits einen strong
Verweis auf sein, view
der seine Unteransichten behält.
IBOutletCollection()
darf nicht seinweak
, sonst gibt es als zurücknil
.strong
Antworten:
Die derzeit von Apple empfohlene Best Practice lautet, dass IBOutlets stark sind, es sei denn, es ist speziell eine Schwäche erforderlich, um einen Aufbewahrungszyklus zu vermeiden. Wie Johannes oben erwähnt hat, wurde dies in der Sitzung "Implementieren von UI-Designs in Interface Builder" von WWDC 2015 kommentiert, in der ein Apple Engineer sagte:
Ich habe auf Twitter einen Ingenieur im IB-Team danach gefragt und er hat bestätigt, dass stark die Standardeinstellung sein sollte und dass die Entwicklerdokumente aktualisiert werden.
https://twitter.com/_danielhall/status/620716996326350848 https://twitter.com/_danielhall/status/620717252216623104
quelle
WARNUNG, veraltete Antwort: Diese Antwort ist gemäß WWDC 2015 nicht aktuell. Die richtige Antwort finden Sie in der oben akzeptierten Antwort (Daniel Hall). Diese Antwort wird aufgezeichnet.
Aus der Entwicklerbibliothek zusammengefasst :
quelle
In der Dokumentation wird zwar empfohlen,
weak
Eigenschaften für Unteransichten zu verwenden, doch scheint es seit iOS 6 in Ordnung zu sein,strong
stattdessen (das Standard-Eigentumsqualifikationsmerkmal) zu verwenden. Dies liegt daran,UIViewController
dass die Ansichten nicht mehr entladen werden.Das heißt, ich bin zwischen dem Gebrauch hin und her gerissen
und
in iOS 6 und danach:
Wenn Sie
weak
eindeutig angeben, möchte der Controller nicht, dass die Schaltfläche in Besitz genommen wird.Das Weglassen
weak
schadet in iOS 6 jedoch nicht ohne das Entladen der Ansicht und ist kürzer. Einige mögen darauf hinweisen, dass dies auch schneller ist, aber ich habe noch keine App gefunden, die wegenweak
IBOutlet
s zu langsam ist .Nichtbenutzung
weak
kann als Fehler empfunden werden.Fazit: Seit iOS 6 können wir das nicht mehr falsch verstehen, solange wir das Entladen von Ansichten nicht verwenden. Zeit für Party. ;)
quelle
nil
manuell einstellen .weak
ist ein bisschen billiger in ARM64: Dweak
Eigenschaften oder__weak
Instanzvariablen der richtige Weg. Ich wollte nur darauf hinweisen, dass hier weniger Fehlerpotential besteht. Daweak
ich auf arm64 billiger bin, habe ich mitweak
IBOutlet
s auf armv7 noch nicht einmal ein echtes Leistungsproblem gesehen. :)strong
macht auch Sinn.strong
ist nur schädlich, wenn Sie das Entladen von Ansichten verwenden - aber wer macht das heutzutage? :)Damit sehe ich kein Problem. Vor ARC habe ich meine IBOutlets immer erstellt
assign
, da sie bereits von ihren Superviews beibehalten werden. Wenn Sie sieweak
erstellen, sollten Sie sie in viewDidUnload nicht ausschließen müssen, wie Sie betonen.Eine Einschränkung: Sie können iOS 4.x in einem ARC-Projekt unterstützen, aber wenn Sie dies tun, können Sie es nicht verwenden
weak
, sodass Sie sie erstellen müssenassign
. In diesem Fall möchten Sie die Referenz trotzdem löschenviewDidUnload
, um dies zu vermeiden ein baumelnder Zeiger. Hier ist ein Beispiel für einen baumelnden Zeigerfehler, den ich erlebt habe:Ein UIViewController verfügt über ein UITextField für die Postleitzahl. Mit CLLocationManager wird der Standort des Benutzers geocodiert und die Postleitzahl festgelegt. Hier ist der Rückruf der Delegierten:
Ich stellte fest, dass
viewDidUnload
der Delegaten-Rückruf eine Ausnahme für den fehlerhaften Zugriff auf self.zip.text auslösen kann , wenn ich diese Ansicht zum richtigen Zeitpunkt verwerfe und nicht self.zip einbinde.quelle
weak
Eigenschaften nicht berücksichtigt werden müssenviewDidUnload
. Aber warum enthält Apples Vorlage zum Erstellen von Verkaufsstellen eine[self setMySubview:nil]
?IBOutlet
sollte aus Leistungsgründen stark sein. Siehe Storyboard-Referenz, Starkes IBOutlet, Szenendock in iOS 9Ab Xcode 7 schlägt es vor
strong
Wenn Sie sich die WWDC 2015-Sitzung 407 zum Implementieren von UI-Designs in Interface Builder ansehen , wird dies vorgeschlagen (Transkript von http://asciiwwdc.com/2015/sessions/407 ).
quelle
In der iOS-Entwicklung unterscheidet sich das Laden von NIB ein wenig von der Mac-Entwicklung.
In der Mac-Entwicklung ist ein IBOutlet normalerweise eine schwache Referenz: Wenn Sie eine Unterklasse von NSViewController haben, bleibt nur die Ansicht der obersten Ebene erhalten, und wenn Sie den Controller freigeben, werden alle Unteransichten und Ausgänge automatisch freigegeben.
UiViewController verwendet die Schlüsselwertcodierung, um die Ausgänge unter Verwendung starker Referenzen festzulegen. Wenn Sie also die Freigabe Ihres UIViewControllers aufheben, wird die Zuordnung der Draufsicht automatisch aufgehoben. Sie müssen jedoch auch alle Steckdosen in der Freigabemethode freigeben.
In diesem Beitrag von der Big Nerd Ranch behandeln sie dieses Thema und erklären auch, warum die Verwendung einer starken Referenz in IBOutlet keine gute Wahl ist (auch wenn dies in diesem Fall von Apple empfohlen wird).
quelle
Eines möchte ich hier hervorheben, und zwar trotz der Aussagen der Apple-Ingenieure in ihrem eigenen WWDC 2015-Video hier:
https://developer.apple.com/videos/play/wwdc2015/407/
Apple ändert ständig seine Meinung zu diesem Thema, was uns sagt, dass es keine einzige richtige Antwort auf diese Frage gibt. Um zu zeigen, dass selbst Apple-Ingenieure in diesem Bereich gespalten sind, werfen Sie einen Blick auf den neuesten Beispielcode von Apple, und Sie werden sehen, dass einige Leute schwach verwenden, andere nicht.
In diesem Apple Pay-Beispiel wird eine schwache Funktion verwendet: https://developer.apple.com/library/ios/samplecode/Emporium/Listings/Emporium_ProductTableViewController_swift.html#//apple_ref/doc/uid/TP40016175-Emporium_ProductTableViewConCer_on
Ebenso wie dieses Bild-in-Bild-Beispiel: https://developer.apple.com/library/ios/samplecode/AVFoundationPiPPlayer/Listings/AVFoundationPiPPlayer_PlayerViewController_swift.html#//apple_ref/doc/uid/TP4001616Pon_Player_Player
Ebenso wie das 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
Wie auch das Beispiel für den Kernspeicherort: https://developer.apple.com/library/ios/samplecode/PotLoc/Listings/Potloc_PotlocViewController_swift.html#//apple_ref/doc/uid/TP40016176-Potloc_PotlocViewController_s
Wie funktioniert die Steuerung Vorschauen Beispiel Ansicht: 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
Ebenso wie das HomeKit-Beispiel: https://developer.apple.com/library/ios/samplecode/HomeKitCatalog/Listings/HMCatalog_Homes_Action_Sets_ActionSetViewController_swift.html#//apple_ref/doc/uid/TP40015048-HeCatalog__
Alle diese sind für iOS 9 vollständig aktualisiert und alle verwenden schwache Steckdosen. Daraus lernen wir, dass A. Das Problem ist nicht so einfach, wie manche Leute es sich vorstellen. B. Apple hat seine Meinung wiederholt geändert und C. Sie können alles verwenden, was Sie glücklich macht :)
Besonderer Dank geht an Paul Hudson (Autor von www.hackingwithsift.com), der mir die Klarstellung und Referenzen für diese Antwort gegeben hat.
Ich hoffe das klärt das Thema etwas besser!
Pass auf.
quelle
Ab WWDC 2015 gibt es eine Sitzung zum Implementieren von UI-Designs in Interface Builder . Rund um die 32min Marke , sagt er , dass Sie immer Ihre machen wollen
@IBOutlet
stark .quelle
Seien Sie sich bewusst,
IBOutletCollection
sollte sein@property (strong, nonatomic)
.quelle
copy
wie es istNSArray
?Es sieht so aus, als ob sich im Laufe der Jahre etwas geändert hat, und jetzt empfiehlt Apple, generell stark zu verwenden. Die Beweise für ihre WWDC-Sitzung befinden sich in Sitzung 407 - Implementieren von UI-Designs in Interface Builder und beginnen um 32:30 Uhr. Meine Notiz von dem, was er sagt, ist (fast, wenn nicht genau, zitiert er ihn):
Steckdosenverbindungen sollten im Allgemeinen stark sein, insbesondere wenn wir eine Unteransicht oder Einschränkung verbinden, die nicht immer von der Ansichtshierarchie beibehalten wird
Möglicherweise ist eine schwache Steckdosenverbindung erforderlich, wenn benutzerdefinierte Ansichten erstellt werden, die auf eine Sicherung in der Ansichtshierarchie verweisen. Dies wird im Allgemeinen nicht empfohlen
Auf anderen Stationen sollte es jetzt immer stark sein, solange einige unserer benutzerdefinierten Ansichten keinen Aufbewahrungszyklus mit einigen der Ansichten in der Ansichtshierarchie erstellen
BEARBEITEN:
Einige mögen die Frage stellen. Wird durch das Beibehalten einer starken Referenz kein Aufbewahrungszyklus erstellt, da der Root-Ansichts-Controller und die besitzende Ansicht den Verweis darauf beibehalten? Oder warum ist das geändert worden? Ich denke, die Antwort ist früher in diesem Vortrag, wenn sie beschreiben, wie die Schreibfedern aus der xib erstellt werden. Es gibt eine separate Feder, die für eine VC und für die Ansicht erstellt wurde. Ich denke, dies könnte der Grund sein, warum sie die Empfehlungen ändern. Trotzdem wäre es schön, eine tiefere Erklärung von Apple zu bekommen.
quelle
Ich denke, dass die wichtigsten Informationen sind: Elemente in xib werden automatisch in Unteransichten der Ansicht angezeigt. Unteransichten ist NSArray. NSArray besitzt seine Elemente. usw. haben starke Hinweise auf sie. In den meisten Fällen möchten Sie also keinen weiteren starken Zeiger (IBOutlet) erstellen.
Und mit ARC müssen Sie nichts tun
viewDidUnload
quelle