Dans la plupart des discussions que j'ai lues, cela indique que créer une propriété atomic ne garantit pas qu'elle est thread-safe, cela garantit simplement que la valeur renvoyée ne sera pas mise à la poubelle à la suite de l'écriture par un objet et par un autre. essayer de le lire en même temps.
Je comprends que ce n'est pas thread-safe car un troisième objet pourrait l'écrire et, bien que l'objet qui y accède ne soit pas gâché, il n'est pas tout à fait sûr de la valeur qu'il recevra si plusieurs objets y écrivent en même temps. temps, et il peut obtenir l'une de leurs valeurs.
Ainsi, lorsque nous disons qu'il ne renverra pas d'ordures, est-ce que les ordures sont dans le sens où si un objet était non atomique et qu'un objet essayait d'y accéder pendant qu'un autre écrivait, il pourrait obtenir le résultat à la mi-écriture, et obtenir seulement une version partielle et incomplète du changement apporté par l'écriture? Est-ce ce que "ordures" signifie en ce sens, et quelles propriétés atomiques aident à prévenir?
Une propriété atomic
dans Objective C garantit que vous ne verrez jamais d'écritures partielles . Lorsqu'un @property
possède l'attribut atomic
, il est impossible d'écrire seulement partiellement la valeur. Le poseur est comme ça:
- (void)setProp:(NSString *)newValue {
[_prop lock];
_prop = newValue;
[_prop unlock];
}
Donc si deux threads veulent écrire la valeur @ "test" et @ "otherTest" en même temps, alorsà tout moment, la propriété ne peut être que la valeur initiale de la propriété ou @ "test" ou @ " otherTest ".nonatomic
est plus rapide, mais la valeur est une valeur erronée et aucune chaîne partielle de @" test "/ @" otherTest "(merci @Gavin) ni aucune autre valeur altérée.
Maisatomic
est seulement compatible avec les threads avec une utilisation simple . Elle n'est pas garantie . Appledoc dit le texte suivant:
Soit un objet
XYZPerson
dans lequel le premier et le dernier d'une personne sont à la fois les noms sont changés en utilisant des accesseurs atomiques d'un thread. Si un autre Le thread accède aux deux noms en même temps, les méthodes de lecture atomique renverra des chaînes complètes (sans crash), mais il n'y a pas de garantir que ces valeurs seront les bons noms par rapport à chaque autre. Si le prénom est utilisé avant la modification, mais le dernier Si vous accédez au nom après la modification, vous obtiendrez un incohérent. paire de noms incompatibles.
Je n'ai jamais eu de problème à utiliser Atomic du tout. J'ai conçu le code de cette façon, qu'il n'y a pas de problème avec les propriétés atomiques.
En réponse à votre troisième paragraphe; essentiellement oui. Un numéro atomique ne peut pas être lu pendant qu'un thread est en train d'écrire le numéro.
Par exemple, si un thread a écrit les deux premiers octets d'un numéro atomique à quatre octets et qu'une lecture de ce numéro est demandée sur un autre thread, cette lecture doit attendre que tous les quatre octets aient été écrits.
Inversement, si un thread a écrit les deux premiers octets d'un nombre non atomique de quatre octets et qu'une lecture de ce numéro est demandée sur un autre thread à ce moment, il lira les deux premiers nouveaux octets de données, mais obtiendra des anciennes d'une précédente opération d'écriture dans les deux autres octets.
La réponse de Robert Harvey est correcte, mais il y a un sous-cas à considérer qui manque souvent aux gens. Considérez ce code: http://Pastebin.com/S7XyJm6G
En plus de vous empêcher de lire des valeurs partiellement écrites, les propriétés atomiques vous empêchent également de récupérer des objets dont vous ne contrôlez pas la durée de vie (ils le font en retenant puis en libérant automatiquement l'objet). Ceci est important dans le code à thread unique, comme dans l'exemple que j'ai lié, mais encore plus important dans le code multithread où un autre thread pourrait provoquer la libération de l'objet sous vous.
En programmation simultanée:
atomique signifie que si une valeur de propriété utilisée pour une opération d'écriture dans un thread (thread n ° 1) et qu'un autre thread (thread n ° 2) tente d'accéder à la valeur atomique pour une opération de lecture ou d'écriture, l'autre thread (thread n ° 2) attend que le thread # 1 termine sa tâche . En d’autres termes, synchronise de façon atomique l’accès de la propriété sur la base du premier arrivé, premier servi.
non atomique signifie que si une valeur de propriété utilisée pour une opération d'écriture dans un thread (thread n ° 1) et qu'un autre thread (thread n ° 2) tente d'accéder à la valeur non atomique soit pour une opération de lecture ou d'écriture, l'autre thread (thread n ° 2) obtient valeur obtient immédiatement l'ancienne valeur
Mise en œuvre explicite de
@property (atomic, keep) NSNumber * count
serait comme ça
- (NSNumber *)count {
NSNumber *count;
@synchronized(self) {
count = [_count retain]; // +1
}
return [count autorelease]; // delayed -1
}
- (void)setCount:(NSNumber *)count {
id oldValue;
@synchronized(self) {
oldValue = _count;
_count = [count retain];
}
[oldValue release];
}
Atomic est le comportement par défaut d'une propriété. Une propriété atomique ajoute un niveau de sécurité du thread lors de l'obtention ou de la définition de valeurs. Autrement dit, le getter et le setter de la propriété seront toujours entièrement terminés, que les autres threads fassent ou non. l'accès à ces propriétés sera un peu plus lent qu'un équivalent non atomique.
Et explicitement nous implémenterions
@property (nonatomic, keep) NSNumber * count
comme ça
- (NSNumber *)count {
return _count;
}
- (void)setCount:(NSNumber *)count {
if (count != _count) {
id oldValue = _count;
_count = [count retain];
[_oldValue release];
}
}
Les propriétés non atomiques ne sont pas thread-safe et renverront directement leurs propriétés. Ce sera plus rapide que les propriétés atomiques, mais comporte évidemment certains risques si des précautions ne sont pas prises.
setter & getter pour ces propriétés non atomiques