В чем разница между атомными и неатомными атрибутами?

Что делать atomic и nonatomic mean в объявлениях свойств?

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

в чем различие между этими тремя?

26 ответов


последние два идентичны; "atomic" - это поведение по умолчанию (обратите внимание, что на самом деле это не ключевое слово; оно определяется только отсутствием nonatomic -- atomic был добавлен в качестве ключевого слова в последних версиях llvm / clang).

предполагая, что вы не @синтезировать реализации метода, атомные и не атомные изменения в сгенерированный код. Если вы пишете свой собственный сеттер/геттеры, атомарный/неатомный/сохранить/назначить/копировать просто рекомендации. (Отмечать: @synthesize теперь является поведением по умолчанию в последних версиях LLVM. Также нет необходимости объявлять переменные экземпляра; они также будут синтезированы автоматически и будут иметь _ добавлено к их имени, чтобы предотвратить случайный прямой доступ).

С помощью "atomic" синтезированный сеттер/геттер гарантирует, что весь значение всегда возвращается из геттера или устанавливается сеттером, независимо от активности сеттера в любом другом потоке. То есть, если поток А в середине геттер в то время как поток B вызывает сеттер, реальный жизнеспособный значение-объект autoreleased, скорее всего, будет возвращено в А.

на nonatomic, такие гарантии не предоставляются. Таким образом, nonatomic значительно быстрее, чем "атомная".

что делает "атомный"не do делает все гарантии о безопасности потока. Если поток A вызывает геттер одновременно с потоком B и C, вызывающим сеттер с разными значения, поток A может получить любое из трех возвращаемых значений - одно до вызова любого сеттера или любое из значений, переданных сеттерам в B и C. Кроме того, объект может получить значение из B или C, невозможно сказать.

обеспечение целостности данных-одна из основных проблем многопоточного программирования-достигается другими средствами.

добавив к этому:

atomicity одного свойства также не может гарантировать поток безопасность при использовании нескольких зависимых свойств.

считаем:

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

в этом случае поток A может переименовывать объект, вызывая setFirstName: и затем вызов setLastName:. Тем временем поток B может вызвать fullName между двумя вызовами потока A и получит новое имя в сочетании со старой фамилией.

чтобы решить эту проблему, вам нужно модель транзакционной. Т. е. какой-то другой вид синхронизации и / или исключение, которое позволяет исключить доступ к fullName при обновлении зависимых свойств.


это объясняется в Apple документация, но ниже приведены некоторые примеры того, что на самом деле происходит. Обратите внимание, что нет ключевого слова" atomic", если вы не укажете" nonatomic", то свойство является атомарным, но указание" atomic " явно приведет к ошибке.

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

- (UITextField *) userName {
    return userName;
}

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

теперь атомный вариант немного сложнее:

//@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_;
    }
}

по существу, атомарная версия должна принять замок для того чтобы гарантировать безопасность потока, и также натыкаясь на счетчик ссылок на объект (и счетчик авторефлексии для его балансировки), чтобы объект гарантированно существовал для вызывающего абонента, в противном случае существует потенциальное условие гонки, если другой поток устанавливает значение, заставляя счетчик ссылок падать до 0.

на самом деле существует большое количество различных вариантов того, как эти вещи работают в зависимости от того, являются ли свойства скалярными значениями или объектами, и как взаимодействуют retain, copy, readonly, nonatomic и т. д. В целом синтезаторы свойств просто знают, как сделать "правильную вещь" для всех комбинаций.


Atomic

  • по умолчанию
  • гарантирует, что данный процесс будет завершен процессором, прежде чем другой процесс получит доступ к переменной
  • не быстро, так как это гарантирует, что процесс завершен полностью

Неатомарный

  • не является поведением по умолчанию
  • быстрее (для синтезированного кода, то есть для переменных, созданных с использованием @property и @synthesize)
  • не thread-safe
  • может привести к неожиданному поведению, когда два разных процесса доступ к одной и той же переменной одновременно

лучший способ понять разницу, используя следующий пример.

предположим, что существует атомарное строковое свойство с именем "name", и если вы вызываете [self setName:@"A"] из потока A, вызов [self setName:@"B"] из потока B и вызовите [self name] из потока C все операции над разными потоками будут выполняться последовательно, что означает, что если один поток выполняет сеттер или геттер, то другие потоки будут ждать.

это делает свойство "name" безопасным для чтения/записи, но если другое thread, D, calls [name release] одновременно эта операция может привести к сбою, потому что здесь нет вызова setter/getter. Это означает, что объект безопасен для чтения/записи (атомарный), но не потокобезопасен, поскольку другие потоки могут одновременно отправлять любые сообщения объекту. Разработчик должен обеспечить потокобезопасность таких объектов.

если свойство "name" было неатомным, то все потоки в приведенном выше примере-A, B, C и D будут выполняться одновременно непредсказуемый результат. В случае atomic либо один из A, B или C будет выполняться первым, но D все равно может выполняться параллельно.


синтаксис и семантика уже хорошо определены другими отличными ответами на этот вопрос. Потому что исполнение и производительность не хорошо, я добавлю свой ответ.

в чем функциональная разница между этими 3?

Я всегда считал atomic по умолчанию довольно любопытным. На уровне абстракции мы работаем, используя атомные свойства для класса в качестве средства для достижения 100% потокобезопасности угловой случай. Для действительно правильных многопоточных программ вмешательство программиста почти наверняка является обязательным. Между тем, эксплуатационные характеристики и исполнение еще не были подробно описаны. Написав несколько сильно многопоточных программ за эти годы, я объявлял свои свойства как nonatomic все время, потому что atomic не был разумным ни для какой цели. Во время обсуждения деталей атомных и неатомных свойств этот вопрос, Я некоторые профилирования столкнулись с некоторыми любопытными результатами.

исполнение

Ok. Первое, что я хотел бы прояснить, это то, что реализация блокировки определяется реализацией и абстрагируется. Луи использует @synchronized(self) в его примере -- я видел это как общий источник путаницы. Реализация не на самом деле использовать @synchronized(self); он использует уровень объекта спин-блокировки. Иллюстрация Луиса хороша для высокого уровня иллюстрация с использованием конструкций, с которыми мы все знакомы, но важно знать, что он не использует @synchronized(self).

другое отличие заключается в том, что атомарные свойства сохранят/освободят цикл ваших объектов в геттере.

производительность

вот интересная часть: производительность с использованием доступа к атомарным свойствам в неоспариваемой (например, однопоточные) случаи могут быть очень быстрыми в некоторых случаях. В менее чем идеальных случаях используйте атомарного доступа может стоить более чем в 20 раз больше накладных расходов nonatomic. В то время как оспаривается случай с использованием 7 потоков был в 44 раза медленнее для трехбайтовой структуры (2.2 GHz Core i7 Quad Core, x86_64). Три-байт struct-это пример очень медленной собственность.

интересное примечание: пользовательские аксессоры трехбайтовой структуры были в 52 раза быстрее, чем синтезированные атомарные аксессоры; или 84% скорости синтезированных неатомных средство доступа.

объекты в оспариваемых случаях также могут превышать 50 раз.

из-за количества оптимизаций и вариаций в реализациях довольно сложно измерить реальные воздействия в этих контекстах. Вы можете часто слышать что-то вроде "доверяйте ему, если вы не профилируете и не находите, что это проблема". Из-за уровня абстракции на самом деле довольно сложно измерить фактическое воздействие. Сбор фактических затрат из профилей может быть очень трудоемким, и из-за абстракции, довольно неточные. Кроме того, ARC vs MRC может иметь большое значение.

так что давайте отойдем,не фокусируясь на реализации доступа к собственности, мы включим обычных подозреваемых, таких как objc_msgSend, и изучить некоторые реальные результаты высокого уровня для многих вызовов NSString getter в неоспариваемой случаях (значения в секундах):

  • MRC | неатомные / реализованные вручную геттеры: 2
  • MRC / неатомный | синтезированы добытчик: 7
  • MRC / atomic / синтезированный геттер: 47
  • ARC / неатомный / синтезированный геттер: 38 (Примечание: ARC добавляет ref count cycling здесь)
  • ARC / atomic / синтезированный геттер: 47

как вы, вероятно, догадались, активность/цикличность подсчета ссылок является значительным вкладчиком с атомами и под дугой. Вы также увидите большие различия в оспариваемых делах.

хотя я обращаю пристальное внимание на производительность, я все еще говорю Семантика Первым!. Между тем, производительность является низким приоритетом для многих проектов. Однако знание деталей выполнения и стоимости используемых вами технологий, безусловно, не повредит. Вы должны использовать правильную технологию для своих нужд, целей и способностей. Надеюсь, это сэкономит вам несколько часов сравнения и поможет вам принять более обоснованное решение при разработке ваших программ.


атомные = потокобезопасность

неатомарный = отсутствие безопасности потока

потокобезопасность:

переменные экземпляра являются потокобезопасными, если они ведут себя правильно при доступе из нескольких потоков, независимо от планирования или чередования выполнения этих потоков средой выполнения и без дополнительной синхронизации или другой координации со стороны вызывающего кода.

в нашем контекст:

если поток изменяет значение экземпляра, измененное значение доступно для всех потоков, и только один поток может изменить значение за раз.

где использовать atomic:

если переменная экземпляра будет доступна в многопоточной среде.

последствия atomic:

не так быстро, как nonatomic, потому что nonatomic не требует никакой работы сторожевого пса над этим из среды выполнения .

где использовать nonatomic:

если переменная экземпляра не будет изменено несколькими потоками, вы можете использовать его. Это улучшает производительность.


Я нашел довольно хорошо поставленное объяснение атомных и неатомных свойств здесь. Вот текст оттуда же:

"атомарный" означает, что он не может быть разбит. В терминах OS / programming вызов атомной функции не может быть прерван - вся функция должна быть выполнена, а не заменена из ЦП обычным переключением контекста ОС, пока она не будет завершена. На всякий случай вы не знали: поскольку CPU может делать только одну вещь в время, ОС поворачивает доступ к процессору для всех запущенных процессов в небольших временных срезах, чтобы дать иллюзия многозадачности. Планировщик CPU может (и делает) прерывать процесс в любой момент его выполнения - даже в середине вызова функции. Поэтому для таких действий, как обновление общих переменных счетчика, где два процесса могут попытаться обновить переменную одновременно, они должны выполняться "атомарно", т. е. каждое действие обновления должно завершиться полностью перед любым другим процессом может быть заменен на CPU.

поэтому я бы предположил, что atomic в этом случае означает, что методы чтения атрибутов не могут быть прерваны-фактически это означает, что переменная(ы), считываемая методом, не может изменить свое значение на полпути, потому что какой-то другой поток/вызов/функция обменивается на CPU.

- за atomic переменные не могут быть прерваны, значение, содержащееся в них в любой момент (блокировка потока), гарантировано нетленным, хотя, обеспечение этой блокировки потока делает доступ к ним медленнее. non-atomic переменные, с другой стороны, не дают такой гарантии, но предлагают роскошь более быстрого доступа. Подводя итог, пойдите с non-atomic когда вы знаете, что ваши переменные не будут доступны несколькими потоками одновременно и ускорить процесс.


после прочтения стольких статей, сообщений переполнения стека и создания демонстрационных приложений для проверки атрибутов свойств переменных я решил собрать всю информацию об атрибутах вместе:

  1. atomic // по умолчанию:
  2. nonatomic
  3. strong = retain // по умолчанию:
  4. weak = unsafe_unretained
  5. retain
  6. assign // По умолчанию
  7. unsafe_unretained
  8. copy
  9. readonly
  10. readwrite // по умолчанию:

в статье атрибуты или модификаторы свойств переменных в iOS вы можете найти все вышеупомянутые атрибуты, и это, безусловно, поможет вам.

  1. atomic

    • atomic означает только одно поток доступа к переменной (статический тип).
    • atomic является потокобезопасным.
    • но это медленно в производительности
    • atomic по умолчанию
    • атомарные аксессоры в среде без мусора (т. е. при использовании retain/release/autorelease) будут использовать блокировку, чтобы гарантировать, что другой поток не мешает правильной настройке / получению значения.
    • на самом деле это не ключевое слово.

    пример:

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

    • nonatomic означает несколько потоков доступа к переменной (динамический тип).
    • nonatomic - это нитей.
    • но это быстро в производительности
    • nonatomic не является поведением по умолчанию. Нам нужно добавить nonatomic ключевое слово в атрибуте собственность.
    • это может привести к неожиданному поведению, когда два разных процесса (потока) обращаются к одной и той же переменной одновременно.

    пример:

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

самый простой ответ Во-первых: нет никакой разницы между вашими вторыми двумя примерами. По умолчанию методы доступа к свойствам являются атомарными.

атомарные аксессоры в среде без мусора (т. е. при использовании retain/release/autorelease) будут использовать блокировку, чтобы гарантировать, что другой поток не мешает правильной настройке / получению значения.

в разделе "производительность и многопоточность" раздел документации Apple Objective-C 2.0 для некоторых других информация и другие соображения при создании многопоточных приложений.


Atomic:

Atomic гарантирует, что доступ к свойству будет выполнен атомарным способом. Например. он всегда возвращает полностью инициализированные объекты, любой get / set свойства в одном потоке должен завершиться, прежде чем другой сможет получить к нему доступ.

если вы представляете, что следующая функция происходит сразу на двух потоках, вы можете понять, почему результаты не будут красивыми.

-(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;
  }

  ...
}

плюсы : Возврат полностью инициализированных объектов каждый раз делает его лучшим выбором в случае многопоточности.

плюсы : Производительность хит, делает выполнение немного медленнее

Неатомарный :

В отличие от Atomic, он не гарантирует, что полностью инициализированный объект возвращается каждый раз.

плюсы : Очень быстрое исполнение.

плюсы : Шансы на ценность мусора в случае многопоточности.


Atomic означает, что только один поток обращается к переменной (статический тип). Atomic является потокобезопасным, но он медленный.

неатомные означает несколько потоков доступа к переменной (динамический тип). Неатомный поток небезопасен, но он быстр.


Atomic is thread safe, это медленно и ну-гарантирует (не гарантирует) это только заблокированное значение предоставляется независимо от того, сколько потоков пытаются получить доступ через ту же зону. При использовании atomic часть кода, записанная внутри этой функции, становится частью критического раздела, к которому может выполняться только один поток за раз.

оно только уверяет безопасность потока; оно не гарантирует это. Я имею в виду вы наймите опытного водителя для вашего автомобиля, но это не гарантирует, что автомобиль не попадет в аварию. Однако вероятность остается ничтожной.

Atomic - он не может быть разбит, поэтому ожидается результат. С неатомным-когда другой поток обращается к зоне памяти, он может изменить ее, поэтому результат неожиданный.

Код Говорить :

Atomic делает геттер и сеттер свойства потокобезопасными. например, если вы написали:

self.myProperty = value;

is поточно-ориентированный.

[myArray addObject:@"Abc"] 

не является потокобезопасным.


нет такого ключевого слова "atomic"

@property(atomic, retain) UITextField *userName;

мы можем использовать, как

@property(retain) UITextField *userName;

см. вопрос переполнения стека у меня возникают проблемы, если я использую @property (atomic,retain)NSString *myString.


на по умолчанию is atomic, это означает, что это стоит вам производительности всякий раз, когда вы используете свойство, но это потокобезопасно. Что делает Objective-C, устанавливается блокировка, поэтому только фактический поток может получить доступ к переменной, пока выполняется сеттер/геттер.

пример с MRC свойства с ivar _internal:

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

Итак, эти последние два одинаковы:

@property(atomic, retain) UITextField *userName;

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

С другой стороны, совсем nonatomic ничего не добавлять в код. Так что является только потокобезопасным, если вы сами кодируете механизм безопасности.

@property(nonatomic, retain) UITextField *userName;

ключевые слова не должны быть записаны как первый атрибут свойства вообще.

не забывайте, что это не означает, что свойство в целом является потокобезопасным. Только вызов метода setter/getter. Но если вы используете сеттер и геттер одновременно с 2 разных потоков, это может быть сломан!


atomic (по умолчанию)

Atomic по умолчанию: если вы ничего не вводите, ваше свойство атомный. Атомарное свойство гарантировано, что если вы попытаетесь прочитать это, вы получите обратно действительное значение. Он не дает никаких гарантий о том, что это значение может быть, но вы получите хорошие данные, а не просто ненужная память. Что это позволяет вам делать, если у вас есть несколько потоки или несколько процессов, указывающих на одну переменную, один поток может прочитать и еще нить может писать. Если они попали в то же время, поток чтения гарантированно получит одно из двух значений: либо до изменения, либо после изменения. Что атомов не дать вам никаких гарантий о том, какие из этих ценностей вы можете получить. Atomic действительно часто путают с потокобезопасностью, и это неверно. Вам нужно гарантировать вашу безопасность потока другое отношение. Однако atomic гарантирует, что если вы попытаетесь прочитать, ты возвращаешься каким-то образом. значение.

неатомической

С другой стороны, неатомный, как вы, вероятно, догадываетесь, просто означает, - не делай ничего атомного."То, что вы теряете, - Это гарантия того, что вы всегда возвращай что-нибудь. Если вы попытаетесь читать в середине напишите, вы можете получить обратно данные мусора. Но, с другой стороны, вы идете немного быстрее. Потому что атомные свойства должны творить магию. чтобы гарантировать, что вы вернете значение, они немного медленнее. Если Это свойство, к которому вы обращаетесь много, вы можете удалить вплоть до неатомного, чтобы убедиться, что вы не несете эту скорость штраф.

подробнее здесь:https://realm.io/news/tmi-objective-c-property-attributes/


прежде чем обсуждать атрибуты @property, вы должны знать, что такое использование @property. @property предлагает способ определения информации, которую класс предназначен для инкапсуляции. Если вы объявите объект / переменную с помощью @property, то этот объект / переменная будет доступна другим классам, импортирующим его класс. Если вы объявляете объект с помощью @property в файле заголовка, то вам нужно синтезировать его с помощью @synthesize в реализации файл.

пример:

.H класс

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

.класс м

@implementation ExampleClass
   @synthesize name;
@end

теперь компилятор синтезирует методы доступа для name.

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

список атрибутов @property : атомный. неатомные. удерживать. копировать. только для чтения. чтение / запись. назначить. сильный.

atomic: это поведение по умолчанию. Если объект объявлен как атомарный, он становится потокобезопасным. Потокобезопасные средства, в то время как только один поток конкретный экземпляр этого класса может иметь контроль над этим объектом.

пример :

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

неатомный: это не потокобезопасно. Вы можете использовать атрибут неатомного свойства, чтобы указать, что синтезированные методы доступа просто устанавливают или возвращают значение напрямую, без каких-либо гарантий того, что произойдет, если одно и то же значение доступно одновременно из разных потоков. По этой причине, это быстрее получить доступ к свойству неатомической, чем атомная один. @property (nonatomic)NSString *name;

сохранить: требуется, когда атрибут является указателем на объект.Метод setter увеличит количество сохранений объекта, так что он будет занимать память в пуле autorelease. @property (retain)NSString *name;

copy: если вы используете copy, вы не можете использовать retain. С помощью экземпляра класса содержит собственную копию. Даже если изменяемая строка задана и впоследствии изменена, экземпляр захватывает любое значение, которое он имеет в момент установки. Нет методов setter и getter будет синтезирован.

@property (copy) NSString *name;

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

readonly: если вы не хотите, чтобы свойство было изменено с помощью метода setter, вы можете объявить свойство readonly. @property (readonly) NSString *name;

readwrite: поведение по умолчанию. Вам не нужно явно указывать атрибут записи.

@property (readwrite) NSString *name;

assign: генерирует сеттер, который присваивает значение переменной экземпляра напрямую, а не копирует или сохраняет его. Это самое лучшее для примитивного типы, такие как NSInteger и CGFloat, или объекты, которыми вы не владеете напрямую, например делегаты.

@property (assign) NSInteger year;

сильный: замена для сохраняет. @property (nonatomic, strong) AVPlayer *player;

unsafe_unretained: в Cocoa и Cocoa Touch есть несколько классов, которые еще не поддерживают слабые ссылки, что означает, что вы не можете объявить слабое свойство или слабую локальную переменную, чтобы отслеживать их. Эти занятия включают в NSTextView, NSFont и NSColorSpace и т. д. Если вам нужно использовать слабое ссылка на один из этих классов, необходимо использовать небезопасную ссылку. Небезопасная ссылка похожа на слабую ссылку в том, что она не поддерживает Связанный объект, но она не будет установлена в ноль, если целевой объект освобожден.

@property (unsafe_unretained) NSObject *unsafeProperty;


Если вы используете свое свойство в многопоточном коде, вы сможете увидеть разницу между неатомными и атомарными атрибутами. Неатомный быстрее, чем атомный, а атомный потокобезопасен, а не неатомный.

Виджаендра Трипати уже привел пример многопоточной среды.


  • -Atomic означает только один поток доступа к переменной (статический тип).
  • -Atomic является потокобезопасным.
  • - но это медленно в производительности

объявления:

как атомарный по умолчанию так,

@property (retain) NSString *name;

и в файле реализации

self.name = @"sourov";

предположим задач связано с тремя свойствами

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

все свойства работайте параллельно (например, асинхронно).

если вы вызываете " имя " из потока A,

и

в то же время, если вы называете

[self setName:@"Datta"]

из потока B,

теперь, если *имя свойства неатомической затем

  • он вернет значение "Datta" для
  • он вернет значение "Datta" для B

вот почему неатомный называется потоком небезопасным, но он быстр в производительности из-за параллельного выполнения

теперь если *свойство name является атомарным

  • это обеспечит значение "суров" для
  • тогда он вернет значение "Datta" для B

вот почему atomic называется потокобезопасным и вот почему он называется read-write safe

такие ситуационная операция будет выполняться последовательно. и медленно в производительности

- неатомный означает множественный доступ потока к переменной (динамический тип).

- неатомный поток небезопасен.

- но это быстро в производительности

- Nonatomic не является поведением по умолчанию, нам нужно добавить неатомное ключевое слово в атрибут свойства.

Для В Swift Подтверждая, что Свифт свойства неатомической в форматы смысле. Одна из причин заключается в том, что вы думаете о том, достаточно ли атомарности каждого свойства для ваших нужд.

ссылка:https://forums.developer.apple.com/thread/25642

для получения дополнительной информации посетите веб-сайт http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html


прежде чем вы начнете: вы должны знать, что каждый объект в памяти должен быть освобожден из памяти для новой записи. Вы не можете просто писать поверх чего-то, как на бумаге. Вы должны сначала удалите (dealloc) его, а затем вы можете написать на него. Если на данный момент стирание сделано (или наполовину сделано) и ничего еще было написано (или наполовину написано), и вы пытаетесь прочитать это может быть очень проблематично! Атомная и неатомная помощь в лечении этого проблема по-разному.

впервые прочитала этой вопрос, а затем прочитать ответ Bbum. Кроме того, прочитайте мое резюме.


atomic всегда будет гарантировать

  • если два разных человека хотят читать и писать одновременно, ваша бумага не будет просто гореть! -- >Ваше приложение никогда не рухнет, даже в условиях гонки.
  • если один человек пытается написать и только написал 4 из 8 букв написано, то не может читать в середине, то чтение может быть сделано только когда все 8 буквами написано --> не читать(вам) будет на что-нить еще написать, т. е. если есть 8 байт в байт, и только 4 байта пишутся--до этого момента, вы не разрешается читать с него. Но поскольку я сказал, что он не рухнет, тогда он будет читать из значения autoreleased, его сохраняют рассчитывать уменьшается на 1 на каком-то этапе в будущем. Если object's сохранить счетчик уменьшается до 0, это освободившему.
    • атомные не гарантируйте безопасность потока, хотя свое полезное для достигать безопасности потока. Безопасность потоков зависит от того, как вы пишете свой код/ из какой очереди потоков Вы читаете/пишете. Оно только гарантирует non-crashable multithreading.

    чего ждать?! Являются многопоточными и потокобезопасность другое?

    да. Многопоточность означает: несколько потоков может одновременно читать общую часть данных, и мы не будем аварийно завершать работу, но это не гарантирует, что вы не читаете из неавтоматизированного значения. С безопасностью потока, гарантировано что Вы читаете не автоматическ-выпущено. Причина, по которой мы не делаем все атомарным по умолчанию, заключается в том, что есть стоимость производительности и для большинства вещей не нужна безопасность потоков. Несколько частей нашего кода нуждаются в этом, и для этих нескольких частей нам нужно написать наш код потокобезопасным способом с помощью блокировок, мьютекс или синхронизация.


    nonatomic

    • поскольку нет такой вещи, как корзина для мусора Mac OS, тогда никого не волнует, всегда ли вы получаете значение ( не гарантирует, что не сбой, потому что он не использует механизм авторелиза.
    • не гарантирует, что будут прочитаны полные письменные значения!
    • быстрее, чем atomic

    в целом они отличаются в 2 аспектах:

    • сбой или нет из-за наличия или отсутствия пула автозапуска.

    • позволяя читать прямо в середине " еще нет готовая запись или пустое значение" или не позволяет и только позволяет читать, когда значение полностью написано.


свойство atomic гарантирует сохранение полностью инициализированного значения независимо от того, сколько потоков делает getter & setter на нем.

свойство nonatomic указывает, что синтезированные методы доступа просто устанавливают или возвращают значение напрямую, без каких-либо гарантий того, что произойдет, если одно и то же значение доступно одновременно из разных потоков.


Atomic означает, что только один поток может получить доступ к переменной за раз (статический тип). Atomic является потокобезопасным, но он медленный.

неатомные означает, что несколько потоков могут получить доступ к переменной в то же время (динамический тип). Неатомный поток небезопасен, но он быстр.


Если вы используете atomic, это означает, что поток будет безопасным и доступным только для чтения. Если вы используете неатомный, это означает, что несколько потоков обращаются к переменной и являются потоками небезопасными, но они выполняются быстро, выполняются операции чтения и записи; это динамический тип.


Atomic: обеспечьте потокобезопасность, заблокировав поток с помощью NSLOCK.

non atomic: не обеспечивает резьбовую безопасность, поскольку нет механизма блокировки резьбы.


чтобы упростить всю путаницу, давайте поймем блокировку мьютекса.Блокировка мьютекса в соответствии с именем блокирует изменяемость объекта.Поэтому, если к объекту обращается класс, ни один другой класс не может получить доступ к тому же объекту.В iOS @sychronise также предусмотрена блокировка мьютекса.Теперь он служит в режиме FIFO и гарантирует, что поток не зависит от двух классов, разделяющих один и тот же экземпляр.Однако, если задача находится в основном потоке, избегайте доступа к объекту с использованием атомарных свойств, поскольку он может содержать ваш пользовательский интерфейс и ухудшать производительность


правда в том, что они используют spin lock для реализации атомарного свойства. Код, как показано ниже:

 static inline void reallySetProperty(id self, SEL _cmd, id newValue, 
      ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy) 
    {
        id oldValue;
        id *slot = (id*) ((char*)self + offset);

        if (copy) {
            newValue = [newValue copyWithZone:NULL];
        } else if (mutableCopy) {
            newValue = [newValue mutableCopyWithZone:NULL];
        } else {
            if (*slot == newValue) return;
            newValue = objc_retain(newValue);
        }

        if (!atomic) {
            oldValue = *slot;
            *slot = newValue;
        } else {
            spin_lock_t *slotlock = &PropertyLocks[GOODHASH(slot)];
            _spin_lock(slotlock);
            oldValue = *slot;
            *slot = newValue;        
            _spin_unlock(slotlock);
        }

        objc_release(oldValue);
    }

атомные свойства : - когда переменная, назначенная с атомарным свойством, это означает, что у нее есть только один доступ к потоку, и она будет потокобезопасной и будет хорошей с точки зрения производительности, будет иметь поведение по умолчанию.

Неатомные Свойства : - когда переменная, назначенная с атомарным свойством, что означает, что она имеет многопоточный доступ, и она не будет потокобезопасной и будет медленной в перспективе производительности, будет иметь поведение по умолчанию и когда два разные темы, хочу получить доступ к переменной, в то же время это даст неожиданные результаты.