Objectif-c ARC: fort vs conserver et faible vs assigner
Il y a deux nouveaux attributs de gestion de la mémoire pour les propriétés introduites par ARC, strong
et weak
.
En dehors de copy
, qui est évidemment quelque chose de complètement différent, y a-t-il des différences entre strong
vs retain
et weak
vs assign
?
D'après ce que je comprends, la seule différence ici est que {[1] } affectera nil
au pointeur, alors que assign
ne le fera pas, ce qui signifie que le programme va planter quand j'envoie un message au pointeur une fois qu'il a été libéré. Mais si j'utilise weak
, cela n'arrivera jamais, car le message envoyé à nil
ne fera rien.
Je ne connais aucune différence entre strong
et retain
.
Est-il une raison pourquoi devrais-je utiliser assign
et retain
dans de nouveaux projets, ou sont le genre d'être obsolète?
8 réponses
De la transition vers les notes de version D'ARC (l'exemple dans la section sur les attributs de propriété).
// The following declaration is a synonym for: @property(retain) MyClass *myObject;
@property(strong) MyClass *myObject;
, Donc strong
est le même que retain
dans une déclaration de propriété.
Pour les projets ARC, j'utiliserais strong
au lieu de retain
, j'utiliserais assign
pour les propriétés primitives C et weak
pour les références faibles aux objets Objective-C.
Après avoir lu tant D'articles StackOverflow messages et applications de démonstration pour vérifier les attributs de propriété variable, j'ai décidé de mettre toutes les informations d'attributs ensemble:
- atomique //par défaut
- non atomique
- fort=conserver //par défaut
- faible
- conserver
- attribuer / / par défaut
- unsafe_unretained
- copier
- lecture seule
- readwrite //par défaut
Ci-dessous est le détaillé lien de l'article où vous pouvez trouver ci-dessus mentionné, tous les attributs, qui va certainement vous aider. Un grand merci à toutes les personnes qui donnent les meilleures réponses ici!!
Attributs ou modificateurs de propriété Variable dans iOS
1.fort (iOS4 = conserver)
- Il dit "gardez ceci dans le tas jusqu'à ce que je ne le pointe Plus"
- en d'autres termes " je suis le propriétaire, vous ne pouvez pas désalloquer cela avant de viser bien avec ce même que conserver"
- vous n'utilisez strong que si vous devez conserver l'objet.
- par défaut, toutes les variables d'instance et les variables locales sont des pointeurs forts.
- nous utilisons généralement strong pour UIViewControllers (les parents de L'élément UI)
- strong est utilisé avec ARC et il vous aide essentiellement, en ne pas avoir à vous soucier du nombre de rétention d'un objet. ARC le libère automatiquement pour vous lorsque vous en avez terminé avec lui.L'utilisation du mot clé strong signifie que vous possédez le objet.
Exemple:
@property (strong, nonatomic) ViewController *viewController;
@synthesize viewController;
2.faible -
- Il dit "gardez ceci aussi longtemps que quelqu'un d'autre le pointe fortement"
- la même chose que de céder, pas de conserver ou de libération
- une référence "faible" est une référence que vous ne conservez pas.
- nous utilisons généralement weak pour IBOutlets (Uiviewcontroller's Childs).Cela fonctionne car l'objet enfant n'a besoin d'exister que tant que l'objet parent le fait.
- une référence faible est une référence ne protège pas l'objet référencé de la collecte par un garbage collector.
- faible est essentiellement assign, une propriété non conservée. Sauf lorsque l'objet est désalloué, le pointeur faible est automatiquement défini sur nil
Exemple :
@property (weak, nonatomic) IBOutlet UIButton *myButton;
@synthesize myButton;
Explication forte et faible, grâce à BJ Homer:
Imaginez que notre objet est un chien, et que le chien veut s'enfuir (être désalloué).
Pointeurs forts sont comme une laisse sur chien. Tant que vous avez le laisse attachée au chien, le chien ne s'en ira pas. Si cinq personnes attachez leur laisse à un chien, (cinq pointeurs forts à un objet), ensuite, le chien ne s'enfuira pas jusqu'à ce que les cinq laisses soient détachées.
Les pointeurs faibles, d'autre part, sont comme des petits enfants pointant vers le chien et dire "Regardez! Un chien!"Tant que le chien est toujours sur le laisse, les petits enfants peuvent encore voir le chien, et ils vont toujours pointer à elle. Dès que tous les les laisses sont détachées, cependant, le chien court loin, peu importe combien de petits enfants pointent vers elle.
Dès que le dernier pointeur fort (laisse) ne pointe plus vers un objet, l'objet sera désalloué, et tous les pointeurs faibles seront mise à zéro.
Lorsque nous utilisons faible?
La seule fois où vous voudriez utiliser weak, c'est si vous vouliez éviter les cycles de rétention (par exemple, le parent conserve l'enfant et l'enfant conserve le parent n'est jamais publier).
3.conserver = fort
- Il est conservé, l'ancienne valeur est libérée et on lui attribue retain spécifie que la nouvelle valeur doit être envoyée
- conserver sur l'affectation et l'ancienne valeur envoyé à libération
- conserver est le même que strong.
- apple dit que si vous écrivez retain, il sera automatiquement converti / fonctionne comme Fort seulement.
- méthodes comme "alloc" incluent un implicite "conserver"
Exemple:
@property (nonatomic, retain) NSString *name;
@synthesize name;
4.attribuer
- assign est la valeur par défaut et effectue simplement une affectation de variable
- assign est un attribut de propriété qui indique au compilateur comment synthétiser l'implémentation du setter de la propriété
- j'utiliserais assign pour les propriétés primitives C et weak pour les références faibles aux objets Objective-C.
Exemple:
@property (nonatomic, assign) NSString *address;
@synthesize address;
Pour autant que je sache, strong
et retain
sont synonymes, donc ils font exactement la même chose.
, Puis le weak
est presque comme assign
, mais automatiquement mis à zéro après que l'objet qu'il désigne, est libéré.
Cela signifie que vous pouvez simplement les remplacer.
Cependant, il existe un cas particulier que j'ai rencontré, où j'ai dû utiliser assign
plutôt que weak
. Disons que nous avons deux propriétés delegateAssign
et delegateWeak
. Dans les deux est stocké notre délégué, c'est nous posséder en ayant la seule référence forte. Le délégué est en train de désallouer, donc notre méthode -dealloc
est également appelée.
// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
[delegateWeak doSomething];
[delegateAssign doSomething];
}
Le délégué est déjà en processus de désallocation, mais pas encore complètement désalloué. Le problème est que weak
les références à lui sont déjà annulé! Property delegateWeak
contient nil, mais delegateAssign
contient un objet valide (avec toutes les propriétés déjà publiées et annulées, mais toujours valides).
// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
[delegateWeak doSomething]; // Does nothing, already nil.
[delegateAssign doSomething]; // Successful call.
}
C'est un cas assez particulier, mais il révélez-nous comment ces variables weak
fonctionnent et quand elles sont annulées.
Non atomique / atomique
- Le nonatomique est beaucoup plus rapide que l'atomique
- Utilisez toujours nonatomic sauf si vous avez une exigence très spécifique pour atomic, ce qui devrait être rare (atomic ne garantit pas la sécurité des threads - seuls les stands accédant à la propriété quand elle est simultanément définie par un autre thread)
Forts/faibles/assigner
- utilisez strong pour conserver les objets-bien que le mot clé retain soit synonyme, il est préférable d'utiliser strong au lieu de cela
- utilisez weak Si vous voulez seulement un pointeur sur l'objet sans le conserver-utile pour éviter les cycles de conservation (ie. délégués) - il supprimera automatiquement le pointeur lorsque l'objet sera libéré
- utilisez assign pour les primatives-exactement comme weak sauf qu'il ne supprime pas l'objet lorsqu'il est libéré (défini par défaut)
(Facultatif)
Copie
- utilisez-le pour créer une copie superficielle de l'objet
- bon pratique pour toujours définir des propriétés immuables à copy-parce que les versions mutables peuvent être passées dans des propriétés immuables, copy s'assurera que vous aurez toujours affaire à un objet immuable
- si un objet immuable est passé, il le conservera - si un objet mutable est passé, il le copiera
En lecture seule
- utilisez-le pour désactiver le paramètre de la propriété (empêche le code de compiler s'il y a une infraction)
- vous pouvez changer ce qui est livré par le getter soit en changeant la variable directement via sa variable d'instance, soit dans la méthode getter elle-même
Le document de Clang sur Objective - C Automatic Reference Counting (ARC) explique clairement les qualificateurs et les modificateurs de propriété:
Il y a quatre qualificatifs de propriété:
- __autoreleasing
- __forte
- __ * unsafe_unretained *
- __la faiblesse de la
Un type est qualifié de propriété non trivialement s'il est qualifié avec __ autoreleasing, __forte , ou __ faible .
Ensuite, il y a six modificateurs de propriété pour la propriété déclarée:
- attribuer implique __*unsafe_unretained* propriété.
- copie implique __strong la propriété, ainsi que le comportement habituel de la sémantique de copie sur le setter.
- conserver implique __strong la propriété.
- strong implique __strong la propriété.
- *unsafe_unretained* implique __*unsafe_unretained* propriété.
- faibles implique __faibles la propriété.
À l'exception de weak, ces modificateurs sont disponibles en modes non-ARC.
Sémantique Sage, les qualificatifs de propriété ont une signification différente dans les cinq opérations gérées: lecture, affectation, initialisation, Destruction et déplacement, dans lequel la plupart du temps nous ne nous soucions que de la différence dans L'opération D'affectation.
Affectation se produit lors de l'évaluation d'un opérateur d'affectation. Le la sémantique varie en fonction de la qualification:
- pour les objets _ _ strong , le nouveau pointee est d'abord conservé; Deuxièmement, la lvalue est chargée avec la sémantique primitive; troisièmement, le nouveau pointee est stocké dans la lvalue avec la sémantique primitive; et enfin, l'ancien pointee est libéré. Ceci n'est pas effectué de manière atomique; une synchronisation externe doit être utilisée pour face des charges et des magasins simultanés.
- pour les objets _ _ faibles , la lvalue est mise à jour pour pointer vers le nouveau pointee, sauf si le nouveau pointee est un objet en cours de désallocation, auquel cas la lvalue est mise à jour vers un pointeur null. Cela doit s'exécuter de manière atomique par rapport aux autres affectations à l'objet, aux lectures de l'objet et à la libération finale du nouveau pointee.
- pour les objets __*unsafe_unretained*, le nouveau pointee est stocké dans lvalue utiliser la sémantique primitive.
- pour les objets _ _ autoreleasing , le nouveau pointee est conservé, autoreleased et stocké dans la lvalue en utilisant la sémantique primitive.
L'autre différence dans la lecture, L'initialisation, la Destruction et le déplacement, se référer à section 4.2 sémantique dans le document .
Fort:
- la propriété ne détruira pas mais seulement une fois que vous définissez la propriété sur nil, l'objet sera-t-il détruit
- par défaut, toutes les variables d'instance et les variables locales sont des pointeurs forts.
- vous n'utilisez strong que si vous devez conserver l'objet.
- nous utilisons généralement strong pour UIViewControllers (les parents de L'élément UI)
- IOS 4 (non-ARC) Nous pouvons utiliser le mot clé Retain
- IOS 5 (ARC) nous pouvons utiliser le mot-clé Fort
Exemple: @propriété (strong, non Atomic) ViewController *viewController;
@synthétiser viewController;
Faible
Par défaut obtient automatiquement et défini sur nil
- nous utilisons généralement weak pour IBOutlets (Uiviewcontroller's Childs) et delegate
- la même chose que de céder, pas de conserver ou de libération
Exemple : @property (faible, Non atomique) IBOutlet UIButton * myButton;
@synthétiser myButton;
Les différences entre strong et retain:
- dans iOS4, strong est égal à retain
- cela signifie que vous possédez l'objet et le gardez dans le tas jusqu'à ce que vous ne le pointiez plus
- Si vous écrivez retain, cela fonctionnera automatiquement comme strong
Les différences entre faible et assign:
- une référence "faible" est une référence que vous ne conservez pas et que vous conservez tant que quelqu'un d'autre le pointe fortement
- lorsque le l'objet est "désalloué", le pointeur faible est automatiquement défini sur nil
- un attribut de propriété" assign " indique au compilateur comment synthétiser l'implémentation du setter de la propriété
strong, weak, assign
les attributs de propriété définissent comment la mémoire de cette propriété sera gérée.
Strong signifie que le nombre de références sera augmenté et la référence à celle-ci sera maintenue tout au long de la vie de l'objet
Weak (référence non forte ), signifie que nous pointons vers un objet mais n'augmentons pas son nombre de références. Il est souvent utilisé lors de la création d'une relation parent-enfant. Le parent a une référence forte à l'enfant, mais l'enfant n'a une faible référence au parent.
Chaque fois utilisé sur var.
Chaque fois utilisé sur un type facultatif.
Se change automatiquement en nil.
En lecture seule , nous pouvons définir la propriété initialement mais elle ne peut pas être modifiée.
Copy , signifie que nous copions la valeur de l'objet lors de sa création. Empêche également sa valeur de changer.