27 votes

faible ou fort pour IBOutlet et d'autres

J'ai changé mon projet à l'ARC, et je ne comprends pas si je dois utiliser strong ou weak pour IBOutlets. Xcode pour ce faire: dans interface builder, si un créer un UILabel par exemple et je le connecte avec le rédacteur en chef adjoint à ma ViewController, c'est de créer ce:

@property (nonatomic, strong) UILabel *aLabel;

Il utilise l' strong, au lieu de cela, j'ai lu un tutoriel sur la RayWenderlich site web qui disent ceci:

Mais pour ces deux propriétés particulières que j'ai d'autres plans. Au lieu de strong,, nous allons déclarer comme weak.

@property (nonatomic, weak) IBOutlet UITableView *tableView;
@property (nonatomic, weak) IBOutlet UISearchBar *searchBar;

Weak est recommandée relation pour toute prise depropriétés. Ces objets de vue sont déjà une partie de la vue du contrôleur de la vue hiérarchie et n'ont pas besoin d'être conservés ailleurs. Le gros avantage de déclaration de vos points de vente weak , c'est qu'il vous fait gagner du temps écrit la viewDidUnload méthode.

Actuellement, nos viewDidUnload ressemble à ceci:

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.tableView = nil;
    self.searchBar = nil;
    soundEffect = nil;
}

Vous pouvez désormais simplifier les suivantes:

- (void)viewDidUnload
{
    [super viewDidUnload];
    soundEffect = nil;
}

Donc, utiliser l' weak, au lieu de l' strong, et de supprimer l'ensemble à néant en l' videDidUnload, au lieu de Xcode utiliser l' strong, et l'utilisation de l' self... = nil dans la viewDidUnload.

Ma question est: quand dois-je utiliser strong, et lors de l' weak? Je veux aussi l'utiliser pour cible de déploiement iOS 4, donc quand dois-je utiliser l' unsafe_unretain? N'importe qui peut les aider à m'expliquer avec un petit tutoriel, lors de l'utilisation de strong, weak et unsafe_unretain avec l'ARC?

60voto

flexaddicted Points 16208

Une règle de pouce

Quand un parent a une référence à un objet enfant, vous devez utiliser un strong de référence. Quand un enfant a une référence à son objet parent, vous devez utiliser un weak de référence ou un unsafe_unretained (si l'ancien n'est pas disponible). Un scénario typique est quand vous avez affaire avec les délégués. Par exemple, un UITableViewDelegate ne pas conserver un contrôleur de classe qui contient une vue de la table.

enter image description here

Voici un schéma simple de présenter les principaux concepts.

Supposons tout d'abord A,B et C sont - strong références. En particulier, C est un strong ref à son parent. Lorsque obj1 est sorti (quelque part), la référence n'existe plus, mais vous avez une fuite car il y a un cycle entre obj1 et obj2. Parler en termes de conserver compte (seulement pour expliquer fins), obj1 a conserver un nombre de 2 (obj2 a un strong référence), tandis que obj2 a conserver un nombre de 1. Si obj1 est sorti, de sa conserver le comte est maintenant de 1 et de ses dealloc méthode n'est pas appelée. obj1 et obj2 restent en mémoire mais on n'a pas une référence à eux: la Fuite.

Sur le contary, si seulement A et B sont des strong refs et C est qualifiée weak tout est ok. Vous n'avez pas de fuites. En fait, quand obj1 est libéré, il libère aussi obj2. Parler en termes de conserver compte, obj1 a conserver un nombre de 1, obj2 a conserver un nombre de 1. Si obj1 est sorti, de sa conserver le comte est maintenant à 0 et son dealloc méthode est appelée. obj1 et obj2 sont supprimées de la mémoire.

Une simple suggestion: Commencer à penser en termes de graphe d'objets lorsque vous traitez avec de l'ARC.

À propos de votre première question, les deux solutions sont valables quand vous avez affaire avec XIBs. En général, weak références sont utilisées lorsque vous traitez avec des cycles de mémoire. Concernant XIBs fichiers, si vous utilisez strong , vous devez définir le nil en viewDidUnload car si vous ne le faites pas, dans la mémoire de faibles conditions, vous pourriez causer des fuites intempestives. Vous ne relâchez pas dans dealloc parce que l'ARC va le faire pour vous. weak au lieu de cela n'a pas besoin que le traitement puisque, lorsque l'objet cible est détruite, ces valeurs sont définies en tant que nil automatiquement. Pas de pendre les pointeurs de plus.

Si vous êtes intéressé, je vous suggère de lire vendredi-qa-2012-04-13-plume-gestion de la mémoire par Mike Cendres.

À propos de votre deuxième question, si vous avez besoin de soutien iOS 4, au lieu de weak vous devez utiliser unsafe_unretained.

À l'intérieur il y a DONC beaucoup de questions/réponses. Voici les principaux:

Comment puis-je remplacer les références faibles lors de l'utilisation de l'ARC et de ciblage de l'iOS 4.0?

Ce type de fuites automatique de comptage de référence en Objective-C pas de prévenir ou de réduire?

à l'aide de l'ARC, la durée de vie du qualificatif de céder et unsafe_unretained

forts / faibles / conserver / unsafe_unretained / affectation

Espérons que cela aide.

Mise à jour

Comme par shaunlim commentaire, à partir de iOS 6 viewDidUnload méthode est obsolète. Ici, je suggère de voir Rob réponse: iOS 6 - viewDidUnload migrer vers didReceiveMemoryWarning?.

10voto

dasdom Points 6905

Vous pouvez utiliser de faibles pour les objets qui sont reliés par IBOutlets à des objets de l'IB, car dans ce cas, les objets seront là aussi longtemps que le superview est là. C'est parce que le superview a une forte pointeur vers son sous-vues.

Si le pointeur de la définition est le seul pointeur vers un objet, vous devez le déclarer comme forte.

Si vous êtes un développeur, je recommande fortement que vous regardez dans les vidéos de la WWDC11 et WWDC12. Une autre bonne ressource est le développement iOS podcast à partir de Stanford.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X