web-dev-qa-db-fra.com

@property conserve, attribue, copie, non atomique en Objective-C

En tant que débutant avec Objective-C, est-ce que quelqu'un peut me donner un aperçu général de la conservation, de la cession, de la copie et de tous les autres documents manquants qui suivent la directive @property? Que font-ils et pourquoi voudrais-je utiliser l'un plutôt que l'autre?

206
Mark Reid

L'article lié à MrMage ne fonctionne plus. Donc, voici ce que j'ai appris dans mon codage (très) court en Objective-C:

nonatomic vs. atomic - "atomic" est la valeur par défaut. Toujours utiliser "nonatomic". Je ne sais pas pourquoi, mais le livre que j'ai lu disait qu'il y avait "rarement une raison" d'utiliser "atomique". (BTW: le livre que j'ai lu est le livre BNR "iOS Programming".)

readwrite vs readonly - "readwrite" est la valeur par défaut. Lorsque vous @ synthétisez, un getter et un passeur seront créés pour vous. Si vous utilisez "readonly", aucun séparateur ne sera créé. Utilisez-le pour une valeur que vous ne souhaitez jamais modifier après l'instanciation de l'objet.

conserver vs copier vs assigner

  • "assign" est la valeur par défaut. Dans le setter créé par @synthesize, la valeur sera simplement assignée à l'attribut. Je crois comprendre que "assign" devrait être utilisé pour les attributs autres que les pointeurs.
  • "conserver" est nécessaire lorsque l'attribut est un pointeur sur un objet. Le setter généré par @synthesize conservera (c'est-à-dire ajoute un nombre de retenues) l'objet. Vous devrez libérer l'objet lorsque vous en aurez fini.
  • "copy" est nécessaire lorsque l'objet est mutable. Utilisez cette option si vous avez besoin de la valeur de l'objet telle qu'elle est à ce moment-là et que vous ne voulez pas que cette valeur reflète les modifications apportées par les autres propriétaires de l'objet. Vous devrez libérer l'objet lorsque vous aurez terminé, car vous conserverez la copie.
267
Blamdarot

Avant de connaître les attributs de @property, vous devez savoir quelle est l’utilisation de @property.

  • @ property offre un moyen de définir les informations qu'une classe est censée encapsuler. Si vous déclarez un objet/une variable à l'aide de @ propriété, cet objet/cette variable sera accessible aux autres classes qui importent sa classe.

  • Si vous déclarez un objet à l'aide de @ property dans le fichier d'en-tête, vous devez le synthétiser à l'aide de @ synthesize dans le fichier d'implémentation. Cela rend l'objet conforme à KVC. Par défaut, le compilateur synthétisera méthodes d'accès pour cet objet.

  • les méthodes d'accès sont les suivantes: setter et getter.

Exemple: .h

@interface XYZClass : NSObject
@property (nonatomic, retain) NSString *name;
@end

.m

@implementation XYZClass
@synthesize name;
@end

Le compilateur va maintenant synthétiser les méthodes d'accès pour name.

XYZClass *obj=[[XYZClass alloc]init];
NSString *name1=[obj name]; // get 'name'
[obj setName:@"liza"]; // first letter of 'name' becomes capital in setter method
  • Liste d'attributs de @ propriété

    atomique, non atomique, conserver, copier, lire, écrire, assigner, fort, getter = méthode, setter = méthode, unsafe_unretained

  • atomic est le comportement par défaut. Si un objet est déclaré comme atomique, il devient thread-safe. Thread-safe signifie que, à la fois, un seul thread d'une instance particulière de cette classe peut avoir le contrôle sur cet objet.

Si le thread exécute la méthode getter, aucun autre thread ne peut exécuter la méthode setter sur cet objet. C'est lent.

@property NSString *name; //by default atomic`
@property (atomic)NSString *name; // explicitly declared atomic`
  • nonatomic n'est pas thread-safe. Vous pouvez utiliser l'attribut de propriété nonatomic pour spécifier que les accesseurs synthétisés définissent ou renvoient directement une valeur, sans aucune garantie quant à ce qui se passe si la même valeur est accédée simultanément à partir de threads différents.

Pour cette raison, il est plus rapide d’accéder à une propriété non atomique qu’à une propriété atomique.

@property (nonatomic)NSString *name;   
  • conserver est requis lorsque l'attribut est un pointeur sur un objet.

La méthode de définition augmentera le nombre de conservations de l'objet, de sorte qu'il occupera de la mémoire dans le pool de libération automatique.

@property (retain)NSString *name;
  • copie Si vous utilisez la copie, vous ne pouvez pas utiliser la conservation. L'utilisation d'une instance de copie de la classe contiendra sa propre copie.

Même si une chaîne modifiable est définie et modifiée par la suite, l'instance capture quelle que soit sa valeur au moment où elle est définie. Aucune méthode setter ni getter ne sera synthétisée.

@property (copy) NSString *name;

maintenant,

NSMutableString *nameString = [NSMutableString stringWithString:@"Liza"];    
xyzObj.name = nameString;    
[nameString appendString:@"Pizza"]; 

name restera inchangé.

  • readonly Si vous ne souhaitez pas autoriser la modification de la propriété via la méthode setter, vous pouvez déclarer la propriété en lecture seule.

Le compilateur générera un getter, mais pas un setter.

@property (readonly) NSString *name;
  • readwrite est le comportement par défaut. Vous n'avez pas besoin de spécifier explicitement l'attribut readwrite.

C'est le contraire de readonly.

@property (readwrite) NSString *name;
  • assign va générer un séparateur qui affecte directement la valeur à la variable d'instance, au lieu de la copier ou de la conserver. Cela convient mieux aux types primitifs tels que NSInteger et CGFloat, ou aux objets que vous ne possédez pas directement, tels que les délégués.

Gardez à l'esprit que conserver et affecter sont fondamentalement interchangeables lorsque la récupération de place est activée.

@property (assign) NSInteger year;
  • fort remplace la conservation.

Il vient avec ARC.

@property (nonatomic, strong) AVPlayer *player; 
  • getter = method Si vous souhaitez utiliser un nom différent pour une méthode getter, il est possible de spécifier un nom personnalisé en ajoutant des attributs à la propriété.

Dans le cas de propriétés booléennes (propriétés qui ont une valeur YES ou NO), il est habituel que la méthode getter commence par le mot "is".

@property (getter=isFinished) BOOL finished;
  • setter = method Si vous souhaitez utiliser un nom différent pour une méthode de définition, il est possible de spécifier un nom personnalisé en ajoutant des attributs à la propriété.

La méthode devrait se terminer par deux points.

@property(setter = boolBool:) BOOL finished;
  • nsafe_unretained Il existe quelques classes dans Cocoa et Cocoa Touch qui ne prennent pas encore en charge les références faibles, ce qui signifie que vous ne pouvez pas déclarer une propriété faible ou une variable locale faible pour les suivre. Ces classes incluent NSTextView, NSFont et NSColorSpace, etc. Si vous devez utiliser une référence faible à l'une de ces classes, vous devez utiliser une référence non sécurisée.

Une référence non sécurisée est similaire à une référence faible en ce sens qu’elle ne garde pas son objet associé en vie, mais ne sera pas définie sur nil si l’objet de destination est désalloué.

@property (unsafe_unretained) NSObject *unsafeProperty;

Si vous devez spécifier plusieurs attributs, incluez-les simplement en tant que liste séparée par des virgules, comme ceci:

@property (readonly, getter=isFinished) BOOL finished;
288
liza

Après avoir lu de nombreux articles, j'ai décidé de rassembler toutes les informations sur les attributs:

  1. atomique // par défaut
  2. non atomique
  3. fort = conserver // par défaut
  4. faible = non sécurisé_unretained
  5. conserver
  6. assign // valeur par défaut
  7. unsafe_unretained
  8. copie
  9. lecture seulement
  10. readwrite // par défaut

Vous trouverez ci-dessous un lien vers l'article détaillé où vous pouvez trouver ces attributs.

Un grand merci à toutes les personnes qui donnent les meilleures réponses ici !!

Attributs de propriété de variable ou modificateurs sous iOS

Voici l'exemple de description de l'article

  1. atomique -Atomique signifie qu'un seul thread accède à la variable (type statique). -Atomic est thread-safe. -mais il est lent en performance -atomic est le comportement par défaut -Accesseurs atomiques dans un environnement non nettoyé (c'est-à-dire lors de l'utilisation de retenue/release/autorelease) utilisera un verrou pour s'assurer qu'un autre thread n'interfère pas avec le paramétrage/obtention correct de la valeur. -ce n'est pas réellement un mot clé.

Exemple :

@property (retain) NSString *name;

@synthesize name;
  1. nonatomic -Nonatomic signifie que plusieurs threads ont accès à la variable (type dynamique). -Nonatomic est le fil dangereux. -mais il est rapide en performance -Nonatomic n'est pas un comportement par défaut, nous devons ajouter un mot clé nonatomic dans l'attribut de propriété. -Il peut en résulter un comportement inattendu lorsque deux processus (threads) différents accèdent à la même variable au même moment.

Exemple:

@property (nonatomic, retain) NSString *name;

@synthesize name;

Explique:

Supposons qu'il existe une propriété de chaîne atomique appelée "nom" et que, si vous appelez [nom du groupe: @ "A"] à partir du fil A, appelez [nom du groupe: @ "B"] à partir du fil B et appelez [nom du compte] thread C, toutes les opérations sur différents threads seront effectuées en série, ce qui signifie que si un thread exécute un programme de lecture ou un programme de lecture, les autres threads attendent. Ceci sécurise la propriété "name" en lecture/écriture, mais si un autre thread D appelle [nom de version] simultanément, cette opération risque de provoquer un blocage, car aucun appel setter/getter n'est impliqué ici. Ce qui signifie qu'un objet est sécurisé en lecture/écriture (ATOMIC) mais pas en sécurité des threads, car d'autres threads peuvent envoyer simultanément tout type de message à l'objet. Le développeur doit garantir la sécurité du filetage pour ces objets.

Si la propriété "name" n'était pas atomique, tous les threads de l'exemple ci-dessus - A, B, C et D s'exécuteront simultanément, produisant ainsi un résultat imprévisible. En cas d'atome, l'un ou l'autre de A, B ou C s'exécutera en premier mais D peut toujours s'exécuter en parallèle.

  1. fort (iOS4 = conserver) -il dit "conservez-le dans le tas jusqu'à ce que je ne le pointe plus", autrement dit "je ' Je suis le propriétaire, vous ne pouvez pas désallouer ceci avant de viser très bien avec cette même chose que de conserver "- Vous utilisez forte uniquement si vous devez conserver l'objet. -Par défaut, toutes les variables d'instance et les variables locales sont des indicateurs puissants. -Nous utilisons généralement fort pour UIViewControllers (les parents de l'élément d'interface utilisateur) -strong est utilisé avec ARC et il vous aide fondamentalement à ne pas avoir à vous soucier du nombre de retenues d'un objet. ARC le publie automatiquement pour vous lorsque vous avez terminé. Le mot-clé strong signifie que vous êtes propriétaire de l'objet.

Exemple:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;
  1. faible (iOS4 = unsafe_unretained) -il dit "conservez-le aussi longtemps que quelqu'un le pointe fortement" -la même chose que assigner, ne pas conserver ou release -Une référence "faible" est une référence que vous ne conservez pas. -Nous utilisons généralement faible pour IBOutlets (Childs d'UIViewController). Cela fonctionne car l'objet enfant n'a besoin d'exister que tant que l'objet parent existe. -a référence faible est une référence qui ne protège pas l'objet référencé de la collecte par un ramasse-miettes. -Weak est essentiellement assign, une propriété non retenue. Sauf que 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, Merci à BJ Homer :

Imaginez que notre objet soit un chien et que celui-ci veuille fuir (être désalloué). Les pointeurs forts sont comme une laisse sur le chien. Tant que vous avez la laisse attachée au chien, celui-ci ne s'enfuira pas. Si cinq personnes attachent leur laisse à un chien (cinq pointeurs puissants à un objet), le chien ne s'enfuira pas tant que les cinq laisses ne sont pas détachées. Les pointeurs faibles, par contre, sont comme des petits enfants qui pointent le chien et disent "Regarde! Un chien!" Tant que le chien est toujours en laisse, les petits enfants peuvent toujours le voir et ils le montrent du doigt. Dès que toutes les laisses sont détachées, cependant, le chien s'enfuit, peu importe le nombre de petits enfants qui le désignent. Dès que le dernier pointeur fort (laisse) ne pointe plus vers un objet, celui-ci sera désalloué et tous les pointeurs faibles seront mis à zéro. Quand on utilise faible? Si vous voulez éviter les cycles de rétention (par exemple, le parent conserve l’enfant et l’enfant le conserve pour qu’il ne soit jamais relâché).

  1. retenue = fort, elle est conservée, l'ancienne valeur est publiée et attribuée. -retain indique que la nouvelle valeur doit être envoyée -retain lors de l'affectation et l'ancien valeur envoyée -release -retain est la même chose que fort. -Apple dit que si vous écrivez conserver, il sera automatiquement converti/fonctionnera comme si c'était fort seulement. -les méthodes comme "alloc" incluent un implicite "conserver"

Exemple:

@property (nonatomic, retain) NSString *name;

@synthesize name;
  1. assign -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 la mise en oeuvre de la propriété. utilisez assign pour les propriétés primitives C et faible pour les références faibles aux objets Objective-C.

Exemple:

@property (nonatomic, assign) NSString *address;

@synthesize address;
  1. unsafe_unretained

    -unsafe_unretained est un qualificatif de propriété qui indique à ARC comment insérer des appels de conservation/libération. -unsafe_unretained est la version ARC de assign.

Exemple:

@property (nonatomic, unsafe_unretained) NSString *nickName;

@synthesize nickName;
  1. copy -copy est requis lorsque l'objet est mutable. -copy spécifie que la nouvelle valeur doit être envoyée -copy lors de l'affectation et l'ancienne valeur envoyée -release. -copy est similaire à Retourner renvoie un objet que vous devez explicitement publier (par exemple, dans dealloc) dans des environnements non nettoyés. -Si vous utilisez copy, vous devez toujours le publier dans dealloc. -Utilisez-le si vous avez besoin de la valeur de l'objet telle qu'elle est à ce moment-là et que vous ne voulez pas que cette valeur reflète les modifications apportées par les autres propriétaires de l'objet. Vous devrez libérer l'objet lorsque vous aurez terminé, car vous conserverez la copie.

Exemple:

@property (nonatomic, copy) NSArray *myArray;

@synthesize myArray;
146
swiftBoy

La propriété Atomic est accessible à un seul thread à la fois. C'est thread safe. La valeur par défaut est atomique .Veuillez noter qu’il n’ya pas de mot clé atomique

Nonatomic signifie que plusieurs threads peuvent accéder à l'article. Il est thread unsafe

Il faut donc faire très attention en utilisant atomique. Comme cela affecterait les performances de votre code

8
Kannan Prasad