Devrait IBOutlets être forte ou faible, en vertu de l'ARC?
Je suis en train d'élaborer exclusivement pour iOS 5 à l'aide de l'ARC. Devrait IBOutlet
s à UIView
s (et sous-classes) être strong
ou weak
?
Suivantes:
@property (nonatomic, weak) IBOutlet UIButton *button;
Serait de se débarrasser de tout cela:
- (void)viewDidUnload
{
//...
self.button = nil;
//...
}
Existe-il des problèmes? Les modèles sont à l'aide de strong
que sont générées automatiquement les propriétés créé lors de la connexion directement à l'en-tête de la "Interface Builder" éditeur, mais pourquoi? Le UIViewController
a déjà un strong
référence à son view
qui conserve son sous-vues.
- Comme une note,
IBOutletCollection()
ne doit pas êtreweak
, sinon elle renvoie commenil
. - Xcode 8.2.1 utilise faibles lors de la création de IBOutlets via interface builder. Cependant beaucoup de réponses ici sur conseille DONC d'utiliser des.
- J'ai juste essayé avec xcode 8.3.2 les faisant glisser à partir de storyboard pour swift fichier et la valeur par défaut est
strong
Vous devez vous connecter pour publier un commentaire.
L'actuelle meilleure pratique recommandée d'Apple est pour IBOutlets être forte sauf faible est spécifiquement nécessaire pour éviter de conserver un cycle. Comme Johannes mentionné ci-dessus, cela a été commenté dans la "mise en Œuvre de l'INTERFACE utilisateur Conceptions d'Interface Builder" session de la WWDC 2015 Apple Ingénieur dit:
J'ai demandé à ce sujet sur Twitter pour un ingénieur de l'équipe du bureau international et il a confirmé que forte doit être la valeur par défaut et que le développeur docs sont en train d'être mis à jour.
https://twitter.com/_danielhall/status/620716996326350848
https://twitter.com/_danielhall/status/620717252216623104
IBOutlets
doit être déclarée faible. Création de solides références habitude de permettre vues pour désallouer. C'est une bonne pratique, mais peut être une préférence personnelle pour ceux qui savent ce qu'ils font. Par exemple, créer une référence forte à un imbriquée dans la sous-vue contrôleur et à la priver de sa vue parent ne serait pas désallouer la mémoire à cause de son fort. Même mieux de faire des sorties en option à la place du implicitement déballé pour éviter les plantages.AVERTISSEMENT, la RÉPONSE DÉPASSÉE: cette réponse n'est pas à jour conformément à la WWDC 2015, pour la réponse correcte, reportez-vous à la accepté de répondre à (Daniel Hall) ci-dessus. Cette réponse restera pour l'enregistrement.
Résumé de la développeur de la bibliothèque:
weak
à la place._topLevelObjectsToKeepAliveFromStoryboard
, mais pas pour le fichier xib, donc, de haut niveau, des objets points de vente peut être faible si vous utilisez la table de montage séquentiel.Bien que la documentation recommande l'utilisation de
weak
sur les propriétés pour les sous-vues, depuis iOS 6, il semble être bien d'utiliserstrong
(la valeur par défaut de la propriété qualificatif) à la place. Cela est provoqué par le changement deUIViewController
que les vues ne sont pas déchargées plus.Cela dit, je suis déchiré entre l'utilisation de
et
dans iOS 6 et après:
À l'aide de
weak
stipule clairement que le contrôleur ne veut pas la propriété du bouton.Mais en omettant
weak
ne fait pas de mal dans iOS 6 sans afficher de déchargement, et est plus courte. Certains pourraient souligner que est également plus rapide, mais je n'ai pas encore rencontrer une application qui est trop lent, à cause deweak
IBOutlet
s.Pas à l'aide de
weak
peut être perçu comme une erreur.Ligne de fond: Depuis iOS 6 on ne peut pas se tromper plus aussi longtemps que nous n'utilisons pas de vue le déchargement. Le temps de faire la fête. 😉
nil
manuellement.weak
est un peu moins cher dans ARM64 😀weak
propriétés ou__weak
les variables d'instance sont la voie à suivre. Je voulais juste signaler qu'il y a moins de risque d'erreur ici. Comme pourweak
moins cher sur arm64, je n'ai même pas vu un vrai problème de performance avecweak
IBOutlet
s sur armv7. 🙂strong
sens ainsi.strong
est dangereux seulement si vous utilisez le mode de déchargement—mais qui n'ces jours-ci? 🙂Je ne vois pas de problème avec ça. Pré-ARC, j'ai toujours fait mon IBOutlets
assign
, car ils sont déjà retenus par leurs superviews. Si vous leur faitesweak
, vous ne devriez pas avoir à néant dans viewDidUnload, comme vous le soulignez.Une mise en garde: Vous pouvez prendre en charge iOS 4.x dans un ARC de projet, mais si vous le faites, vous ne pouvez pas utiliser
weak
, de sorte que vous avez à faireassign
, auquel cas vous auriez encore envie à néant la référence dansviewDidUnload
pour éviter une balançant pointeur. Voici un exemple d'une balançant pointeur de bug, je l'ai connu:Un UIViewController a un UITextField pour le code postal. Il utilise CLLocationManager de géocodage inversé de la localisation de l'utilisateur et de définir le code postal. Voici le délégué de rappel:
J'ai trouvé que si j'ai rejeté ce point de vue au bon moment et n'a pas de néant self.zip dans
viewDidUnload
, le délégué de rappel pourrait jeter une mauvaise accès exception sur de soi.zip.texte.weak
propriétés n'ont pas besoin d'être annulé dansviewDidUnload
. Mais pourquoi Apple modèle pour la création de points de vente comprennent une[self setMySubview:nil]
?En développement iOS PLUME de chargement est un peu différent de Mac développement.
Dans Mac développement d'un IBOutlet est généralement une référence faible: si vous avez une sous-classe de NSViewController seulement l'affichage de niveau supérieur seront conservés et quand vous dealloc le contrôleur toutes ses sous-vues et points de vente sont libérés automatiquement.
UiViewController utiliser la Valeur de la Clé de Codage pour définir les points de vente à l'aide de solides références. Ainsi, lorsque vous dealloc votre UIViewController, la vue de dessus sera automatiquement libéré, mais vous devez également de libérer tous ses points de vente dans le dealloc méthode.
Dans ce post, à partir de la Big Nerd Ranch, ils couvrent ce sujet et aussi d'expliquer pourquoi, à l'aide d'une référence forte dans IBOutlet n'est pas un bon choix (même si elle est recommandée par Apple dans ce cas).
IBOutlet
doit être forte, pour des raisons de performances. Voir Storyboard de Référence, Fort IBOutlet, Scène Dock iOS 9De Xcode 7, il suggère
strong
Si vous regardez la WWDC 2015 session 407 La mise en œuvre de l'INTERFACE utilisateur Conceptions d'Interface Builder, il suggère (transcription de http://asciiwwdc.com/2015/sessions/407)
Une chose que je tiens à souligner ici, et qui est, en dépit de ce que les ingénieurs Apple ont déclaré dans leur propre WWDC 2015 vidéo ici:
https://developer.apple.com/videos/play/wwdc2015/407/
Apple ne cesse de changer leur esprit sur le sujet, qui nous dit qu'il n'y a pas de bonne réponse à cette question. Pour montrer que même les ingénieurs d'Apple sont divisés sur ce sujet, jetez un oeil à Apple les plus récents
exemple de code, et vous verrez que certaines personnes utilisent les faibles, et certains ne le font pas.
Cette Apple Pay exemple utilise faibles:
https://developer.apple.com/library/ios/samplecode/Emporium/Listings/Emporium_ProductTableViewController_swift.html#//apple_ref/doc/uid/TP40016175-Emporium_ProductTableViewController_swift-DontLinkElementID_8
Comme cette image dans l'image exemple:
https://developer.apple.com/library/ios/samplecode/AVFoundationPiPPlayer/Listings/AVFoundationPiPPlayer_PlayerViewController_swift.html#//apple_ref/doc/uid/TP40016166-AVFoundationPiPPlayer_PlayerViewController_swift-DontLinkElementID_4
Comme les Lister exemple:
https://developer.apple.com/library/ios/samplecode/Lister/Listings/Lister_ListCell_swift.html#//apple_ref/doc/uid/TP40014701-Lister_ListCell_swift-DontLinkElementID_57
Comme l'Emplacement de Noyau exemple:
https://developer.apple.com/library/ios/samplecode/PotLoc/Listings/Potloc_PotlocViewController_swift.html#//apple_ref/doc/uid/TP40016176-Potloc_PotlocViewController_swift-DontLinkElementID_6
Comme la vue-contrôleur de la prévisualisation exemple:
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
Comme le HomeKit exemple:
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
Tous ceux qui sont entièrement mis à jour pour iOS 9, et toutes les utiliser de faibles points de vente. À partir de cela, nous apprenons que A. Le problème n'est pas aussi simple que certains gens font dehors pour être. B. Apple a changé leur esprit à plusieurs reprises, et C. Vous pouvez utiliser tout ce qui vous rend heureux 🙂
Un merci spécial à Paul Hudson (auteur de http://www.hackingwithsift.com) qui m'a donné les précisions et les références pour cette réponse.
J'espère que cela clarifie le sujet un peu mieux!
Prendre soin.
De la WWDC 2015 il y a une session sur La mise en œuvre de l'INTERFACE utilisateur Conceptions d'Interface Builder. Autour de la 32min marque qu'il vous dit que vous voulez toujours faire de votre
@IBOutlet
forte.Être conscient,
IBOutletCollection
devrait être@property (strong, nonatomic)
.copy
que c'est unNSArray
?On dirait que quelque chose a changé au fil des ans et maintenant Apple recommande d'utiliser des solides en général. Les preuves de la WWDC session est en session 407 - la mise en Œuvre de l'INTERFACE utilisateur Conceptions d'Interface Builder et commence à 32:30. Ma note de ce qu'il dit est (presque, si pas exactement, citant lui):
raccords de sortie en général devrait être forte, surtout si l'on connecter une sous-vue ou de la contrainte, ce n'est pas toujours conservés par la
afficher la hiérarchie
la faiblesse de la connexion de la sortie peut être nécessaire lors de la création de vues personnalisées qui a une référence à quelque chose en retour dans le point de vue de la hiérarchie
et en général, il n'est pas recommandé
Dans d'autres paroisses, il devrait être toujours forte maintenant, aussi longtemps que certains de nos affichage personnalisé ne crée pas de conserver cycle avec certains de les afficher dans la vue de la hiérarchie
EDIT :
Certains peuvent se poser la question. Ne gardant avec une référence forte ne crée pas de conserver cycle de la vue racine contrôleur et le propriétaire de vue conserve la référence à elle? Ou pourquoi ce qui a changé est-il arrivé?
Je pense que la réponse est plus haut dans cette discussion quand ils décrivent la façon dont les plumes sont créés à partir de la xib. Il existe une autre plume créé pour un VC et pour la vue. Je pense que cela pourrait être la raison pourquoi ils changent les recommandations. Néanmoins, il serait agréable d'avoir une explication plus approfondie de Apple.
Je pense que la plupart des informations importantes sont:
Éléments xib sont automatiquement dans les sous-vues de vue. Les sous-vues est NSArray. NSArray possède des éléments. etc ont de fortes présomptions sur eux. Ainsi, dans la plupart des cas, vous ne voulez pas créer un autre pointeur (IBOutlet)
Et avec l'ARC, vous n'avez pas besoin de faire quoi que ce soit dans
viewDidUnload