ios - Quelle est la différence entre les attributs atomiques et non atomiques?




objective-c properties atomic (22)

Que signifient les nonatomic atomic et nonatomic atomic dans les déclarations de propriété?

@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;

Quelle est la différence opérationnelle entre ces trois?


Answers

  • -Atomique signifie qu'un seul thread accède à la variable (type statique).
  • -Atomic est thread safe.
  • mais il est lent en performance

Comment déclarer:

Comme atomique est par défaut,

@property (retain) NSString *name;

ET dans le fichier de mise en œuvre

self.name = @"sourov";

Supposons qu'une tâche liée à trois propriétés soit

 @property (retain) NSString *name;
 @property (retain) NSString *A;
 @property (retain) NSString *B;
 self.name = @"sourov";

Toutes les propriétés fonctionnent parallèlement (comme de manière asynchrone).

Si vous appelez "nom" du fil A ,

Et

En même temps, si vous appelez

[self setName:@"Datta"]

à partir du fil B ,

Maintenant, si la propriété * name est non atomique, alors

  • Il retournera la valeur "Datta" pour A
  • Il retournera la valeur "Datta" pour B

C'est pourquoi le non-atomique est appelé thread dangereux mais il est rapide dans la performance en raison de l'exécution parallèle

Maintenant, si la propriété * name est atomique

  • Il va assurer la valeur "Sourov" pour A
  • Puis Il retournera la valeur "Datta" pour B

C'est pourquoi atomic est appelé thread Safe et c'est pourquoi il est appelé en lecture-écriture sûr

Une telle opération de situation fonctionnera en série. Et lent dans la performance

- Nonatomic signifie que plusieurs threads accèdent à la variable (type dynamique).

- Nonatomic est un fil dangereux.

- mais c'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é.

Pour In Swift Confirmant que les propriétés Swift sont non atomiques dans le sens d'ObjC. Une raison est que vous pensez si l'atomicité par propriété est suffisante pour vos besoins.

Référence: https://forums.developer.apple.com/thread/25642

Pour plus d'informations s'il vous plaît visitez le site Web http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html


Si vous utilisez votre propriété dans du code multithread, vous pourrez voir la différence entre les attributs non atomiques et atomiques. Nonatomic est plus rapide que atomique et atomique est thread-safe, pas nonatomic.

Vijayendra Tripathi a déjà donné un exemple pour un environnement multithread.


Atomic means only one thread can access the variable at a time (static type). Atomic is thread-safe, but it is slow.

Nonatomic means multiple threads can access the variable at same time (dynamic type). Nonatomic is thread-unsafe, but it is fast.


Atomique

  • est le comportement par défaut
  • veillera à ce que le processus actuel est complété par le CPU, avant qu'un autre processus accède à la variable
  • n'est pas rapide, car il garantit que le processus est entièrement terminé

Non-Atomique

  • n'est PAS le comportement par défaut
  • plus rapide (pour le code synthétisé, c'est-à-dire pour les variables créées avec @property et @synthesize)
  • pas thread-safe
  • peut entraîner un comportement inattendu, lorsque deux processus différents accèdent à la même variable en même temps

Atomic: Ensure thread-safety by locking the thread using NSLOCK.

Non atomic: Doesn't ensure thread-safety as there is no thread-locking mechanism.


The atomic property ensures to retain a fully initialised value irrespective of how many threads are doing getter & setter on it.

The nonatomic property specifies that synthesized accessors simply set or return a value directly, with no guarantees about what happens if that same value is accessed simultaneously from different threads.


La valeur par défaut est atomic , ce qui signifie que cela vous coûte des performances chaque fois que vous utilisez la propriété, mais elle est sûre pour les threads. Ce que fait Objective-C est un verrou, donc seul le thread réel peut accéder à la variable, tant que setter / getter est exécuté.

Exemple avec MRC d'une propriété avec un ivar _internal:

[_internal lock]; //lock
id result = [[value retain] autorelease];
[_internal unlock];
return result;

Donc, ces deux derniers sont les mêmes:

@property(atomic, retain) UITextField *userName;

@property(retain) UITextField *userName; // defaults to atomic

D'un autre côté, nonatomic n'ajoute rien à votre code. Donc, il n'y a de thread sécurisé que si vous codez le mécanisme de sécurité vous-même.

@property(nonatomic, retain) UITextField *userName;

Les mots-clés n'ont pas besoin d'être écrits en tant que premier attribut de propriété.

N'oubliez pas que cela ne signifie pas que la propriété dans son ensemble est sûre pour les threads. Seul l'appel de méthode du setter / getter est. Mais si vous utilisez un setter et ensuite un getter en même temps avec 2 threads différents, il pourrait être cassé aussi!


atomique (par défaut)

Atomic est la valeur par défaut: si vous ne tapez rien, votre propriété est atomique. Une propriété atomique est garantie que si vous essayez d'en lire, vous obtiendrez une valeur valide. Cela ne donne aucune garantie quant à la valeur de cette valeur, mais vous obtiendrez de bonnes données, pas seulement de la mémoire indésirable. Ce que cela vous permet de faire est si vous avez plusieurs threads ou plusieurs processus pointant vers une seule variable, un thread peut lire et un autre thread peut écrire. Si elles frappent en même temps, le thread du lecteur est garanti d'obtenir l'une des deux valeurs: soit avant le changement ou après le changement. Ce que l'atomique ne vous donne pas est une sorte de garantie sur laquelle de ces valeurs vous pourriez obtenir. Atomic est souvent confondu avec thread-safe, et ce n'est pas correct. Vous devez garantir votre sécurité de thread d'autres façons. Cependant, atomic garantira que si vous essayez de lire, vous récupérez une sorte de valeur.

non atomique

D'un autre côté, non atomique, comme vous pouvez probablement le deviner, signifie simplement «ne faites pas ce truc atomique». Ce que vous perdez, c'est la garantie que vous récupérez toujours quelque chose. Si vous essayez de lire au milieu d'une écriture, vous pouvez récupérer les données de vidage. Mais, d'un autre côté, vous allez un peu plus vite. Parce que les propriétés atomiques doivent faire un peu de magie pour garantir que vous récupérerez une valeur, elles sont un peu plus lentes. Si c'est une propriété à laquelle vous avez beaucoup accès, vous voudrez peut-être passer à Nonatomic pour vous assurer que vous n'encourez pas cette pénalité de vitesse.

Voir plus ici: https://realm.io/news/tmi-objective-c-property-attributes/


Après avoir lu tant d'articles, affiche et fait des applications de démonstration pour vérifier les attributs des propriétés des variables, j'ai décidé de mettre toutes les informations d'attributs ensemble:

  1. atomic // Par défaut
  2. nonatomic
  3. strong = retain // Par défaut
  4. weak = unsafe_unretained
  5. retain
  6. assign // Par défaut
  7. unsafe_unretained
  8. copy
  9. readonly
  10. readwrite // Par défaut

Dans l'article Attributs de propriété de variable ou modificateurs dans iOS, vous pouvez trouver tous les attributs mentionnés ci-dessus, et cela va certainement vous aider.

  1. atomic

    • atomic 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
    • Les accesseurs atomiques dans un environnement non garbage collect (c'est-à-dire lors de l'utilisation de retain / release / autorelease) utiliseront un verrou pour s'assurer qu'un autre thread n'interfère pas avec le réglage / l'obtention de la valeur correcte.
    • Ce n'est pas réellement un mot-clé.

    Exemple:

        @property (retain) NSString *name;
    
        @synthesize name;
    
  2. nonatomic

    • nonatomic signifie que plusieurs threads accèdent à la variable (type dynamique).
    • nonatomic est thread-dangereux.
    • Mais c'est rapide en performance
    • nonatomic n'est PAS un comportement par défaut. Nous devons ajouter le mot clé nonatomic dans l'attribut de propriété.
    • Cela peut entraîner un comportement inattendu, lorsque deux processus différents (threads) accèdent à la même variable en même temps.

    Exemple:

        @property (nonatomic, retain) NSString *name;
    
        @synthesize name;
    

J'ai trouvé une explication assez bien posée des propriétés atomiques et non-atomiques here . Voici un texte pertinent de la même:

«atomique» signifie qu'il ne peut pas être décomposé. En termes d'OS / programmation, un appel de fonction atomique est un appel qui ne peut pas être interrompu - toute la fonction doit être exécutée, et non échangée hors de la CPU par le changement de contexte habituel du système d'exploitation jusqu'à ce qu'il soit terminé. Juste au cas où vous ne le sauriez pas: puisque le CPU ne peut faire qu'une seule chose à la fois, le système d'exploitation tourne l'accès au processeur à tous les processus en cours dans des tranches de temps, pour donner l' illusion du multitâche. Le planificateur de CPU peut (et interrompt) un processus à n'importe quel moment de son exécution - même en cas d'appel de fonction moyenne. Ainsi, pour des actions comme la mise à jour de variables de comptage partagées où deux processus peuvent essayer de mettre à jour la variable en même temps, ils doivent être exécutés "atomiquement", c'est-à-dire que chaque action de mise à jour doit être terminée. CPU.

Donc, je devinerais que atomique dans ce cas signifie que les méthodes de lecture d'attributs ne peuvent pas être interrompues - ce qui signifie que les variables lues par la méthode ne peuvent pas changer leur valeur à mi-chemin parce qu'un autre thread / appel / fonction échangé sur le CPU.

Parce que les variables atomic ne peuvent pas être interrompues, la valeur qu'elles contiennent à tout moment est (thread-lock) garantie d'être non corrompue , bien que, en s'assurant que ce verrou thread rend leur accès plus lent. non-atomic autre côté, non-atomic variables non-atomic ne garantissent pas ce genre de choses mais offrent le luxe d'un accès plus rapide. Pour résumer, allez avec non-atomic quand vous savez que vos variables ne seront pas accessibles par plusieurs threads simultanément et accélérer les choses.


Atomique

Atomic garantit que l'accès à la propriété sera effectuée de manière atomique. Par exemple, il retourne toujours un objet entièrement initialisé, tout get / set d'une propriété sur un thread doit se terminer avant qu'un autre puisse y accéder.

Si vous imaginez la fonction suivante se produisant sur deux threads à la fois, vous pouvez voir pourquoi les résultats ne seraient pas jolis.

-(void) setName:(NSString*)string
{
  if (name)
  {
    [name release]; 
    // what happens if the second thread jumps in now !?
    // name may be deleted, but our 'name' variable is still set!
    name = nil;
  }

  ...
}

Avantages: Le retour des objets entièrement initialisés à chaque fois fait le meilleur choix en cas de multi-threading.

Inconvénients: Performance hit, rend l'exécution un peu plus lente

Non-Atomique:

Contrairement à Atomic, il ne garantit pas le retour de l'objet entièrement initialisé à chaque fois.

Avantages: Exécution extrêmement rapide.

Inconvénients: Les chances de la valeur des ordures en cas de multi-threading.


Before discussing about the attributes of @property, you should know what is the use of @property. @property offers a way to define the information that a class is intended to encapsulate. If you declare an object/variable using @property, then that object/variable will be accessible to other classes importing its class. If you declare an object using @property in the header file, then you have to synthesize it using @synthesize in the implementation file.

Exemple:

.h class

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

.m class

@implementation ExampleClass
   @synthesize name;
@end

Now the compiler will synthesize accessor methods for name.

ExampleClass *newObject=[[ExampleClass alloc]init];
NSString *name1=[newObject name]; // get 'name'
[obj setName:@“Tiger”];

List of attributes of @property : atomic. nonatomic. retain. copy. readonly. readwrite. assign. strong.

atomic : It is the default behaviour. If an object is declared as atomic then it becomes thread-safe. Thread-safe means, at a time only one thread of a particular instance of that class can have the control over that object.

Exemple :

@property NSString *name; //by default atomic
@property (atomic)NSString *name; // explicitly declared atomic

nonatomic: It is not thread-safe. You can use the nonatomic property attribute to specify that synthesized accessors simply set or return a value directly, with no guarantees about what happens if that same value is accessed simultaneously from different threads. For this reason, it's faster to access a nonatomic property than an atomic one. @property (nonatomic)NSString *name;

retain: is required when the attribute is a pointer to an object.The setter method will increase retain count of the object, so that it will occupy memory in autorelease pool. @property (retain)NSString *name;

copy: If you use copy, you can't use retain. Using copy instance of the class will contain its own copy. Even if a mutable string is set and subsequently changed, the instance captures whatever value it has at the time it is set. No setter and getter methods will be synthesized.

@property (copy) NSString *name;

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

readonly: If you don't want to allow the property to be changed via setter method, you can declare the property readonly. @property (readonly) NSString *name;

readwrite: is the default behaviour. You don't need to specify readwrite attribute explicitly.

@property (readwrite) NSString *name;

assign: will generate a setter which assigns the value to the instance variable directly, rather than copying or retaining it. This is best for primitive types like NSInteger and CGFloat, or objects you don't directly own, such as delegates.

@property (assign) NSInteger year;

strong: is a replacement for retain. @property (nonatomic, strong) AVPlayer *player;

unsafe_unretained: There are a few classes in Cocoa and Cocoa Touch that don't yet support weak references, which means you can't declare a weak property or weak local variable to keep track of them. These classes include NSTextView, NSFont and NSColorSpace,etc. If you need to use a weak reference to one of these classes, you must use an unsafe reference. An unsafe reference is similar to a weak reference in that it doesn't keep its related object alive, but it won't be set to nil if the destination object is deallocated.

@property (unsafe_unretained) NSObject *unsafeProperty;


To simplify the entire confusion let us understand mutex lock.Mutex lock as per the name locks the mutability of the object.So if the object is accessed by a class no other class can access the same object.In iOS @sychronise also provide the mutex lock.Now it serve in FIFO mode and ensures the flow is not affected by two classes sharing the same instance.However if the task is on main thread avoid accessing object using atomic properties as it may hold your UI and degrade the performance


Atomique = sécurité du filetage

Non-atomique = Pas de sécurité de filetage

Sécurité du filetage:

Les variables d'instance sont thread-safe si elles se comportent correctement à partir de plusieurs threads, indépendamment de la planification ou de l'entrelacement de l'exécution de ces threads par l'environnement d'exécution et sans synchronisation supplémentaire ou autre coordination de la part du code appelant.

Dans notre contexte:

Si un thread modifie la valeur de l'instance, la valeur modifiée est disponible pour tous les threads, et un seul thread peut changer la valeur à la fois.

Où utiliser atomic :

si la variable d'instance est accessible dans un environnement multithread.

Implication de l' atomic :

Pas aussi vite que nonatomic parce que nonatomic n'exige aucun travail de surveillance sur cela de l'exécution.

Où utiliser nonatomic :

Si la variable d'instance ne va pas être modifiée par plusieurs threads, vous pouvez l'utiliser. Cela améliore les performances.



La syntaxe et la sémantique sont déjà bien définies par d'autres excellentes réponses à cette question. Parce que l' exécution et la performance ne sont pas bien détaillées, j'ajouterai ma réponse.

Quelle est la différence fonctionnelle entre ces 3?

J'avais toujours considéré l'atomique comme un défaut assez curieux. Au niveau de l'abstraction, nous travaillons, en utilisant des propriétés atomiques pour une classe comme un véhicule pour atteindre 100% de la sécurité du fil est un cas de coin. Pour les programmes multithread vraiment corrects, l'intervention du programmeur est presque certainement une exigence. Pendant ce temps, les caractéristiques de performance et d'exécution n'ont pas encore été détaillées en détail. Ayant écrit des programmes fortement multithread au cours des années, j'avais déclaré mes propriétés comme nonatomic atomiques tout le temps parce que l'atomique n'était pas raisonnable pour n'importe quel but. Au cours de la discussion des détails des propriétés atomiques et non atomiques de cette question , j'ai fait quelques profils rencontrés des résultats curieux.

Exécution

D'accord. La première chose que je voudrais clarifier est que l'implémentation de verrouillage est définie et implémentée par l'implémentation. Louis utilise @synchronized(self) dans son exemple - j'ai vu cela comme une source commune de confusion. L'implémentation n'utilise pas réellement @synchronized(self) ; il utilise des verrous de spin au niveau de l'objet. L'illustration de Louis est bonne pour une illustration de haut niveau utilisant des constructions que nous connaissons tous, mais il est important de savoir qu'elle n'utilise pas @synchronized(self) .

Une autre différence est que les propriétés atomiques conservent / libèrent vos objets dans le getter.

Performance

Voici la partie intéressante: Les performances utilisant des accès aux propriétés atomiques dans des cas non contestés (par exemple, mono-thread) peuvent être vraiment très rapides dans certains cas. Dans des cas moins nonatomic , l'utilisation d'accès atomiques peut coûter plus de 20 fois le nonatomic de non nonatomic . Alors que le cas contesté utilisant 7 threads était 44 fois plus lent pour la structure à trois octets ( Core i7 Quad Core de 2,2 GHz, x86_64). La structure à trois octets est un exemple de propriété très lente.

Note intéressante: Les accesseurs définis par l'utilisateur de la structure à trois octets étaient 52 fois plus rapides que les accesseurs atomiques synthétisés; ou 84% de la vitesse des accesseurs non atomiques synthétisés.

Les objets dans les cas contestés peuvent également dépasser 50 fois.

En raison du nombre d'optimisations et de variations dans les implémentations, il est assez difficile de mesurer les impacts réels dans ces contextes. Vous pourriez souvent entendre quelque chose comme «Faites-le confiance, à moins que vous ne fassiez un profil et que vous trouviez que c'est un problème». En raison du niveau d'abstraction, il est en réalité assez difficile de mesurer l'impact réel. Le glanage des coûts réels à partir des profils peut prendre beaucoup de temps et, en raison des abstractions, être très imprécis. De même, ARC vs MRC peut faire une grande différence.

Revenons donc à l'implémentation des accès aux propriétés, nous incluons les suspects habituels comme objc_msgSend , et examinons des résultats de haut niveau réels pour de nombreux appels à un getter NSString dans des cas non contestés (valeurs en secondes):

  • MRC | nonatomique | getters implémentés manuellement: 2
  • MRC | nonatomique | getter synthétisé: 7
  • MRC | atomique | getter synthétisé: 47
  • ARC | nonatomique | getter synthétisé: 38 (note: l'ARC ajoute le compte de l'arbitre cycliste ici)
  • ARC | atomique | getter synthétisé: 47

Comme vous l'avez probablement deviné, l'activité de comptage de référence / cyclisme est un contributeur significatif avec les atomes et sous ARC. Vous verriez également de plus grandes différences dans les cas contestés.

Bien que je porte une attention particulière à la performance, je dis toujours Semantics First! . Pendant ce temps, la performance est une faible priorité pour de nombreux projets. Cependant, connaître les détails d'exécution et les coûts des technologies que vous utilisez ne fait aucun mal. Vous devez utiliser la bonne technologie pour vos besoins, vos objectifs et vos capacités. J'espère que cela vous permettra d'économiser quelques heures de comparaisons et de vous aider à prendre une décision plus éclairée lors de la conception de vos programmes.


Atomique signifie qu'un seul thread accède à la variable (type statique). Atomic est thread-safe, mais il est lent.

Nonatomic signifie que plusieurs threads accèdent à la variable (type dynamique). Nonatomic est thread-dangereux, mais c'est rapide.


Atomic est thread-safe , il est lent et il assure (pas garanti) que seule la valeur verrouillée est fournie quel que soit le nombre de threads qui tentent d'accéder sur la même zone. Lorsque vous utilisez atomic, un morceau de code écrit à l'intérieur de cette fonction devient la partie de la section critique, à laquelle un seul thread peut s'exécuter à la fois.

Il assure seulement la sécurité de filetage; cela ne garantit pas cela. Ce que je veux dire, c'est que vous embaucher un chauffeur expert pour votre voiture, mais il ne garantit pas que la voiture ne rencontrera pas un accident. Cependant, la probabilité reste la moindre.

Atomique - il ne peut pas être décomposé, donc le résultat est attendu. Avec nonatomic - quand un autre thread accède à la zone mémoire, il peut le modifier, le résultat est inattendu.

Code Talk:

Atomic rend le getter et le setter de la propriété threads sûrs. par exemple si vous avez écrit:

self.myProperty = value;

est thread safe.

[myArray addObject:@"Abc"] 

n'est PAS thread safe.


Les deux derniers sont identiques; "atomic" est le comportement par défaut ( notez qu'il n'est pas réellement un mot-clé, il est spécifié uniquement par l'absence de nonatomic - atomic été ajouté comme mot-clé dans les versions récentes de llvm / clang).

En supposant que vous êtes @synthesizing les implémentations de la méthode, atomic vs non-atomique modifie le code généré. Si vous écrivez votre propre setter / getters, atomic / nonatomic / retain / assign / copy sont simplement consultatifs. (Note: @synthesize est maintenant le comportement par défaut dans les versions récentes de LLVM Il n'est pas non plus nécessaire de déclarer les variables d'instance, elles seront également synthétisées automatiquement et seront ajoutées à leur nom pour empêcher un accès direct accidentel.

Avec "atomic", le setter / getter synthétisé veillera à ce qu'une valeur entière soit toujours renvoyée par le getter ou définie par le setter, indépendamment de l'activité du setter sur n'importe quel autre thread. C'est-à-dire que si le thread A est au milieu du getter alors que le thread B appelle le setter, une valeur viable réelle - un objet auto-libéré, très probablement - sera retournée à l'appelant dans A.

En nonatomic , aucune de ces garanties ne sont faites. Ainsi, non nonatomic est considérablement plus rapide que "atomique".

Qu'est-ce que "atomique" ne fait pas est de garantir la sécurité des threads. Si le thread A appelle le getter simultanément avec les threads B et C appelant le setter avec des valeurs différentes, le thread A peut récupérer l'une des trois valeurs renvoyées - celle précédant l'appel des setters ou l'une des valeurs passées dans les setters dans B et C. De même, l'objet peut finir avec la valeur de B ou C, aucun moyen de dire.

Assurer l'intégrité des données - l'un des principaux défis de la programmation multithread - est réalisé par d'autres moyens.

Ajoutant à ceci:

atomicity d'une seule propriété ne peut pas non plus garantir la sécurité des threads lorsque plusieurs propriétés dépendantes sont en jeu.

Considérer:

 @property(atomic, copy) NSString *firstName;
 @property(atomic, copy) NSString *lastName;
 @property(readonly, atomic, copy) NSString *fullName;

Dans ce cas, le thread A pourrait renommer l'objet en appelant setFirstName: puis en appelant setLastName: En attendant, le thread B peut appeler fullName entre les deux appels du thread A et recevra le nouveau prénom couplé avec l'ancien nom.

Pour y remédier, vous avez besoin d'un modèle transactionnel . C'est-à-dire un autre type de synchronisation et / ou d'exclusion qui permet d'exclure l'accès à fullName pendant la mise à jour des propriétés dépendantes.


Ceci est expliqué dans la documentation d'Apple, mais voici quelques exemples de ce qui se passe réellement. Notez qu'il n'y a pas de mot-clé "atomic", si vous ne spécifiez pas "nonatomic" alors la propriété est atomique, mais spécifier "atomic" explicitement entraînera une erreur.

//@property(nonatomic, retain) UITextField *userName;
//Generates roughly

- (UITextField *) userName {
    return userName;
}

- (void) setUserName:(UITextField *)userName_ {
    [userName_ retain];
    [userName release];
    userName = userName_;
}

Maintenant, la variante atomique est un peu plus compliquée:

//@property(retain) UITextField *userName;
//Generates roughly

- (UITextField *) userName {
    UITextField *retval = nil;
    @synchronized(self) {
        retval = [[userName retain] autorelease];
    }
    return retval;
}

- (void) setUserName:(UITextField *)userName_ {
    @synchronized(self) {
      [userName_ retain];
      [userName release];
      userName = userName_;
    }
}

Fondamentalement, la version atomique doit prendre un verrou afin de garantir la sécurité du fil, et aussi cogner le compte ref sur l'objet (et le compte autorelease pour l'équilibrer) de sorte que l'objet est garanti pour l'appelant, sinon il est une condition de concurrence potentielle si un autre thread est en train de définir la valeur, entraînant la chute du nombre de ref à 0.

Il existe en fait un grand nombre de variantes différentes de la façon dont ces choses fonctionnent, selon que les propriétés sont des valeurs scalaires ou des objets, et comment interagissent retain, copy, readonly, nonatomic, etc. En général, les synthétiseurs de propriété savent juste faire la «bonne chose» pour toutes les combinaisons.


La meilleure façon de comprendre la différence consiste à utiliser l'exemple suivant.

Supposons qu'il existe une propriété de chaîne atomique appelée "name", et si vous appelez [self setName:@"A"] du thread A, appelez [self setName:@"B"] du thread B, et appelez [self name] depuis thread C, alors toutes les opérations sur des threads différents seront effectuées en série, ce qui signifie que si un thread exécute un setter ou getter, alors d'autres threads attendent.

Cela rend la propriété "nom" sûre en lecture / écriture, mais si un autre thread, D, appelle [name release] simultanément, cette opération peut provoquer un plantage car il n'y a pas d'appel de setter / getter impliqué ici. Ce qui signifie qu'un objet est en lecture / écriture sécurisé (ATOMIC), mais pas thread-safe car un autre thread peut simultanément envoyer n'importe quel type de message à l'objet. Le développeur doit garantir la sécurité des threads pour de tels objets.

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


Le document de Clang sur le comptage automatique des références Objective-C (ARC) explique clairement les qualificatifs de propriété et les modificateurs:

Il y a quatre qualificatifs de propriété:

  • __ autoreleasing
  • __ fort
  • __ * unsafe_unretained *
  • __ faible

Un type est qualifié de propriété non triviale s'il est qualifié avec __ autoreleasing , __ strong ou __ weak .

Ensuite, il y a six modificateurs de propriété pour la propriété déclarée:

  • assign implique __ * unsafe_unretained * la propriété.
  • copy implique __ forte propriété, ainsi que le comportement habituel de la sémantique de copie sur le setter.
  • conserver implique __ forte propriété.
  • fort implique __ forte propriété.
  • * unsafe_unretained * implique __ * unsafe_unretained * la propriété.
  • faible implique __ faible propriété.

À l'exception de faible , ces modificateurs sont disponibles dans les modes non-ARC.

Du point de vue de la sémantique, 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 lesquelles la plupart du temps nous nous soucions seulement de la différence dans l'opération d'assignation.

L'affectation se produit lors de l'évaluation d'un opérateur d'affectation. La sémantique varie en fonction de la qualification:

  • Pour __ objets forts , la nouvelle pointe est d'abord conservée; deuxièmement, la lvalue est chargée de sémantique primitive; troisièmement, la nouvelle pointee est stockée dans la lvalue avec une sémantique primitive; et enfin, la vieille pointee est libérée. Ceci n'est pas effectué atomiquement; Une synchronisation externe doit être utilisée pour sécuriser cette fonction face aux charges et aux magasins simultanés.
  • Pour __ objets faibles , la lvalue est mise à jour pour pointer vers la nouvelle pointe, à moins que la nouvelle pointee soit un objet en cours de désallocation, auquel cas la valeur lvalue est mise à jour en un pointeur nul. Cela doit s'exécuter atomiquement par rapport à d'autres affectations à l'objet, à des lectures depuis l'objet, et à la version finale de la nouvelle pointee.
  • Pour les objets __ * unsafe_unretained *, la nouvelle pointe est stockée dans la lvalue en utilisant la sémantique primitive.
  • Pour __ objets autoreleasing , la nouvelle pointe est conservée, auto-libérée et stockée dans la lvalue en utilisant la sémantique primitive.

L'autre différence dans Lecture, Init, Destruction et Déplacement, s'il vous plaît se référer à la Section 4.2 Sémantique dans le document .





ios objective-c properties atomic