Je développe exclusivement pour iOS 5 en utilisant ARC. Les IBOutlet
s à UIView
s (et les sous-classes) devraient strong
- weak
ils être ou ?
Le suivant:
@property (nonatomic, weak) IBOutlet UIButton *button;
Se débarrasserait de tout cela:
- (void)viewDidUnload
{
// ...
self.button = nil;
// ...
}
Y a-t-il des problèmes à le faire? Les modèles utilisent tout strong
comme les propriétés générées automatiquement créées lors de la connexion directe à l'en-tête à partir de l'éditeur «Interface Builder», mais pourquoi? Le a UIViewController
déjà une strong
référence à son view
qui conserve ses sous-vues.
IBOutletCollection()
ne doit pas êtreweak
, sinon il revient commenil
.strong
Réponses:
Le courant recommandé les meilleures pratiques d'Apple est pour IBOutlets d'être forte à moins faible est particulièrement nécessaire pour éviter retain cycle. Comme Johannes l'a mentionné ci-dessus, cela a été commenté dans la session "Implémentation de conceptions d'interface utilisateur dans Interface Builder" de la WWDC 2015 où un ingénieur Apple a déclaré:
J'ai demandé à ce sujet sur Twitter à un ingénieur de l'équipe IB et il a confirmé que strong devrait être la valeur par défaut et que les documents du développeur sont en cours de mise à jour.
https://twitter.com/_danielhall/status/620716996326350848 https://twitter.com/_danielhall/status/620717252216623104
la source
AVERTISSEMENT, RÉPONSE ANCIENNE : cette réponse n'est pas à jour selon WWDC 2015, pour la bonne réponse se référer à la réponse acceptée (Daniel Hall) ci-dessus. Cette réponse restera enregistrée.
Résumé de la bibliothèque des développeurs :
la source
Bien que la documentation recommande d'utiliser des
weak
propriétés pour les sous-vues, depuis iOS 6, il semblestrong
approprié d'utiliser (le qualificatif de propriété par défaut) à la place. Cela est dû au changement dans le faitUIViewController
que les vues ne sont plus déchargées.Cela dit, je suis déchiré entre l'utilisation
et
dans iOS 6 et versions ultérieures:
L'utilisation
weak
indique clairement que le contrôleur ne souhaite pas être propriétaire du bouton.Mais l'omission
weak
ne fait pas de mal dans iOS 6 sans déchargement de vue et est plus courte. Certains peuvent signaler que c'est aussi plus rapide, mais je n'ai pas encore rencontré d'application trop lente à cause de l'weak
IBOutlet
art.Ne pas utiliser
weak
peut être perçu comme une erreur.Conclusion: depuis iOS 6, nous ne pouvons plus nous tromper tant que nous n'utilisons pas le déchargement de vue. Il est temps de faire la fête. ;)
la source
nil
manuellement tous vos points de vente .weak
est un peu moins cher dans ARM64: Dweak
propriétés ou les__weak
variables d'instance sont la voie à suivre. Je voulais juste souligner qu'il y a moins de risque d'erreur ici. Quant àweak
être moins cher sur arm64, je n'ai même pas vu de problème de performance réel avecweak
IBOutlet
s sur armv7. :)strong
cela a également du sens.strong
n'est nuisible que si vous utilisez le déchargement de vues, mais qui le fait de nos jours? :)Je ne vois aucun problème avec cela. Avant l'ARC, j'ai toujours créé mes IBOutlets
assign
, car ils sont déjà conservés par leurs superviews. Si vous les faitesweak
, vous ne devriez pas avoir à les supprimer dans viewDidUnload, comme vous le faites remarquer.Une mise en garde: vous pouvez prendre en charge iOS 4.x dans un projet ARC, mais si vous le faites, vous ne pouvez pas l'utiliser
weak
, vous devrez donc les créerassign
, auquel cas vous voudrez toujours annuler la référenceviewDidUnload
pour éviter un pointeur pendant. Voici un exemple de bogue de pointeur pendant que j'ai rencontré:Un UIViewController a un UITextField pour le code postal. Il utilise CLLocationManager pour inverser le géocodage de l'emplacement de l'utilisateur et définir le code postal. Voici le rappel du délégué:
J'ai constaté que si je rejetais cette vue au bon moment et que je ne mettais pas self.zip à zéro
viewDidUnload
, le rappel du délégué pourrait lever une mauvaise exception d'accès sur self.zip.text.la source
weak
propriétés n'ont pas besoin d'être préciséesviewDidUnload
. Mais pourquoi le modèle d'Apple pour la création de points de vente comprend-il un[self setMySubview:nil]
?IBOutlet
devrait être solide, pour des raisons de performances. Voir Storyboard Reference, Strong IBOutlet, Scene Dock dans iOS 9Depuis Xcode 7, il suggère
strong
Si vous regardez la session 407 de la WWDC 2015 sur la mise en œuvre des conceptions d'interface utilisateur dans Interface Builder , cela suggère (transcription de http://asciiwwdc.com/2015/sessions/407 )
la source
Dans le développement iOS, le chargement NIB est un peu différent du développement Mac.
Dans le développement Mac, une IBOutlet est généralement une référence faible: si vous avez une sous-classe de NSViewController, seule la vue de niveau supérieur sera conservée et lorsque vous désallouez le contrôleur, toutes ses sous-vues et sorties sont automatiquement libérées.
UiViewController utilise le codage des valeurs clés pour définir les sorties à l'aide de références fortes. Ainsi, lorsque vous désallouez votre UIViewController, la vue de dessus sera automatiquement désallouée, mais vous devez également désallouer toutes ses sorties dans la méthode dealloc.
Dans cet article du Big Nerd Ranch , ils couvrent ce sujet et expliquent également pourquoi l'utilisation d'une référence forte dans IBOutlet n'est pas un bon choix (même si cela est recommandé par Apple dans ce cas).
la source
Une chose que je souhaite souligner ici, et ce, malgré ce que les ingénieurs d'Apple ont déclaré dans leur propre vidéo WWDC 2015 ici:
https://developer.apple.com/videos/play/wwdc2015/407/
Apple ne cesse de changer d'avis sur le sujet, ce qui nous dit qu'il n'y a pas de bonne réponse unique à cette question. Pour montrer que même les ingénieurs d'Apple sont divisés sur ce sujet, jetez un coup d'œil à l'exemple de code le plus récent d'Apple, et vous verrez que certaines personnes utilisent faible, et d'autres non.
Cet exemple d'Apple Pay utilise faible: https://developer.apple.com/library/ios/samplecode/Emporium/Listings/Emporium_ProductTableViewController_swift.html#//apple_ref/doc/uid/TP40016175-Emporium_ProductTableViewController_swift
Tout comme cet exemple d'image dans l'image: https://developer.apple.com/library/ios/samplecode/AVFoundationPiPPlayer/Listings/AVFoundationPiPPlayer_PlayerViewController_swift.html#//apple_ref/doc/uid/TP40016166-AVFoundationPiPController
Tout comme l'exemple Lister: https://developer.apple.com/library/ios/samplecode/Lister/Listings/Lister_ListCell_swift.html#//apple_ref/doc/uid/TP40014701-Lister_ListCell_swift-DontLinkElementID_57
Tout comme l'exemple de l'emplacement principal: https://developer.apple.com/library/ios/samplecode/PotLoc/Listings/Potloc_PotlocViewController_swift.html#//apple_ref/doc/uid/TP40016176-Potloc_PotlocViewController_swift-
Tout comme l'exemple de prévisualisation du contrôleur de vue: https://developer.apple.com/library/ios/samplecode/ViewControllerPreviews/Listings/Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift.html#//apple_ref/doc_uidPort
Tout comme l'exemple HomeKit: https://developer.apple.com/library/ios/samplecode/HomeKitCatalog/Listings/HMCatalog_Homes_Action_Sets_ActionSetViewController_swift.html#//apple_ref/doc/uid/TP40015048-HMCatalogSelect
Tous ceux-ci sont entièrement mis à jour pour iOS 9 et utilisent tous des prises faibles. De cela, nous apprenons que A. Le problème n'est pas aussi simple que certains le prétendent. B. Apple a changé d'avis à plusieurs reprises, et C. Vous pouvez utiliser tout ce qui vous rend heureux :)
Un merci spécial à Paul Hudson (auteur de www.hackingwithsift.com) qui m'a donné la clarification et les références pour cette réponse.
J'espère que cela clarifie un peu mieux le sujet!
Prends soin de toi.
la source
Depuis la WWDC 2015, il y a une session sur la mise en œuvre de conceptions d'interface utilisateur dans Interface Builder . Autour de la marque des 32 minutes, il dit que vous voulez toujours vous
@IBOutlet
fortifier .la source
Soyez conscient,
IBOutletCollection
devrait l'être@property (strong, nonatomic)
.la source
copy
car c'est unNSArray
?Il semble que quelque chose ait changé au fil des ans et maintenant Apple recommande d'utiliser le fort en général. Les preuves de leur session WWDC se trouvent dans la session 407 - Implémentation de conceptions d'interface utilisateur dans Interface Builder et commencent à 32h30. Ma note d'après ce qu'il dit est (presque, sinon exactement, le citant):
les connexions de sortie en général doivent être solides, surtout si nous connectons une sous-vue ou une contrainte qui n'est pas toujours conservée par la hiérarchie des vues
une connexion de sortie faible peut être nécessaire lors de la création de vues personnalisées ayant une référence à quelque chose de sauvegarde dans la hiérarchie des vues et en général, il n'est pas recommandé
Dans d'autres quartiers, il devrait toujours être fort tant que certaines de nos vues personnalisées ne créent pas de cycle de conservation avec une partie de la vue dans la hiérarchie des vues.
ÉDITER :
Certains peuvent poser la question. Le conserver avec une référence forte ne crée-t-il pas un cycle de conservation car le contrôleur de vue racine et la vue propriétaire la conservent? Ou pourquoi cela a-t-il changé? Je pense que la réponse est plus tôt dans cet exposé quand ils décrivent comment les plumes sont créées à partir du xib. Il existe une pointe distincte créée pour un VC et pour la vue. Je pense que cela pourrait être la raison pour laquelle ils modifient les recommandations. Ce serait quand même bien d'obtenir une explication plus approfondie d'Apple.
la source
Je pense que les informations les plus importantes sont les suivantes: les éléments de xib sont automatiquement en sous-vues. Subviews est NSArray. NSArray possède ses éléments. etc ont des pointeurs forts sur eux. Donc, dans la plupart des cas, vous ne voulez pas créer un autre pointeur fort (IBOutlet)
Et avec ARC, vous n'avez rien à faire
viewDidUnload
la source