Что означают atomic
и nonatomic
в объявлениях свойств?
@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;
Какова операционная разница между этими тремя?
Последние два идентичны; "atomic" - это поведение по умолчанию (), но это не ключевое слово, а только отсутствие - nonatomic
atomic
было добавлено как ключевое слово в последних версиях llvm/лязг).
Предполагая, что вы @synthesizing реализации метода, атомный или неатомный изменяет сгенерированный код. Если вы пишете свой собственный сеттер/получатель, атомарное/неатомическое/сохранение/назначение/копирование являются просто рекомендательными. (Примечание: @synthesize теперь является поведением по умолчанию в последних версиях LLVM. Также нет необходимости объявлять переменные экземпляра, они также будут автоматически синтезированы и будут иметь _
, добавленные к их имени, чтобы предотвратить случайный прямой доступ).
С "атомарным" синтезированный сеттер/получатель гарантирует, что целое значение всегда возвращается из получателя или задается установщиком независимо от активности сеттера в любом другом потоке. То есть, если поток A находится в середине получателя, тогда как поток B вызывает сеттер, фактическое жизнеспособное значение - скорее всего, автореализованный объект будет возвращен вызывающему абоненту в A.
В nonatomic
такие гарантии не предоставляются. Таким образом, nonatomic
значительно быстрее, чем "атомный".
То, что "атомный" делает не, делает все гарантии безопасности потоков. Если поток 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 documentation, но ниже приведены некоторые примеры того, что на самом деле происходит. Обратите внимание, что нет "атомарного" ключевого слова, если вы не укажете "неатомический", тогда свойство является атомарным, но явно указывать "атомный" приведет к ошибке.
//@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_;
}
}
В принципе, атомная версия должна блокировать, чтобы гарантировать безопасность потока, а также набрасывает количество ссылок на объект (и счет авторезиста, чтобы сбалансировать его), чтобы гарантированный объект существовал для вызывающего, в противном случае существует потенциальное состояние гонки, если другой поток задает значение, заставляя отсчет ref сбросить до 0.
На самом деле существует большое количество различных вариантов того, как эти вещи работают в зависимости от того, являются ли свойства скалярными значениями или объектами и как сохранять, копировать, читать, неатомически и т.д. взаимодействовать. В общем, синтезаторы свойств просто знают, как делать "правильную вещь" для всех комбинаций.
Лучший способ понять разницу - использовать следующий пример.
Предположим, что существует свойство атомной строки, называемое "имя", и если вы вызываете [self setName:@"A"]
из потока A, вызовите [self setName:@"B"]
из потока B и вызовите [self name]
из потока C, тогда все операции с разными потоками будут выполняться серийно, что означает, что если один поток выполняет сеттер или получатель, то другие потоки будут ждать.
Это делает свойство "имя" безопасным для чтения/записи, но если другой поток, D, вызывает [name release]
одновременно, то эта операция может привести к сбою, потому что здесь нет вызова setter/getter. Это означает, что объект безопасен для чтения/записи (ATOMIC), но не является потокобезопасным, поскольку другие потоки могут одновременно отправлять сообщения любого типа в объект. Разработчик должен обеспечить безопасность потоков для таких объектов.
Если свойство "name" было неатомным, то все потоки в приведенном выше примере - A, B, C и D будут выполняться одновременно с получением любого непредсказуемого результата. В случае атома, сначала выполняется один из A, B или C, но D может выполняться параллельно.
Синтаксис и семантика уже хорошо определены другими отличными ответами на этот вопрос. Поскольку выполнение и производительность не очень подробные, я добавлю свой ответ.
Какова функциональная разница между этими 3?
Я всегда считал атомным по умолчанию довольно любопытным. На уровне абстракции мы работаем, используя атомные свойства для класса в качестве транспортного средства для достижения 100% -ной защиты от потока. Для действительно правильных многопоточных программ вмешательство программиста почти наверняка является обязательным требованием. Между тем характеристики и исполнение производительности еще не были детально изучены. На протяжении многих лет написав несколько многопоточных программ, я все время декларировал свои свойства как nonatomic
, потому что атомал не был разумным для каких-либо целей. Во время обсуждения деталей атомных и неатомических свойств этот вопрос, я сделал некоторые профилирования, столкнувшись с некоторыми любопытными результатами.
Исполнение
Ok. Первое, что я хотел бы прояснить, это то, что реализация блокировки определяется и абстрагируется. Луис использует @synchronized(self)
в своем примере - я видел это как общий источник замешательства. Реализация на самом деле не использует @synchronized(self)
; он использует блокировку уровня объекта. Иллюстрации Луи хорошо подходят для иллюстрации на высоком уровне, используя конструкции, с которыми мы все знакомы, но важно знать, что это не использует @synchronized(self)
.
Другим отличием является то, что атомарные свойства будут сохранять/освобождать цикл ваших объектов внутри получателя.
Производительность
Здесь интересная часть: Производительность с использованием доступа к атомным свойствам в неоспоримых (например, однопоточных) случаях может быть очень быстрой в некоторых случаях. В менее идеальных случаях использование атомных доступов может стоить более 20 раз над служебными данными nonatomic
. В то время как аргумент Оспариваемый с использованием 7 потоков был в 44 раза медленнее для трехбайтовой структуры (2.2 GHz Core i7 Quad Core, x86_64). Трехбайтовая структура является примером очень медленного свойства.
Интересная заметка: пользовательские аксессоры трехбайтовой структуры были в 52 раза быстрее, чем синтезированные атомарные аксессоры; или 84% - скорость синтезированных неатомических аксессуаров.
Объекты в оспариваемых случаях также могут превышать 50 раз.
Из-за количества оптимизаций и изменений в реализациях довольно сложно измерить влияние реального мира в этих контекстах. Вы часто можете услышать что-то вроде "Доверяйте ему, если вы не профиль и не найдете, что это проблема". Из-за уровня абстракции на самом деле довольно сложно измерить фактическое воздействие. Исчезновение фактических затрат из профилей может быть очень трудоемким, а из-за абстракций довольно неточным. Кроме того, ARC против MRC может иметь большое значение.
Итак, давайте шаг назад, не делая упор на реализацию имущества доступов, мы будем включать обычные подозреваемые, как objc_msgSend
, и рассмотрим некоторые реальные результаты высокого уровня для многих вызовов к NSString
геттер в неоспоримой случаи (значения в секундах):
Как вы, наверное, догадались, активность счетчика/цикличность значительного вклада в атомику и под ARC. Вы также увидите большие различия в оспариваемых случаях.
Хотя я уделяю пристальное внимание производительности, я все еще говорю Семантика первая!. Между тем, производительность является низким приоритетом для многих проектов. Однако, зная подробности исполнения и стоимость технологий, которые вы используете, конечно, не повредит. Вы должны использовать правильную технологию для своих нужд, целей и способностей. Надеюсь, это сэкономит вам несколько часов сравнений и поможет вам принять более обоснованное решение при разработке ваших программ.
Atomic= безопасность потока
Неатомный= безопасность потока
Переменные экземпляра являются потокобезопасными, если они ведут себя корректно при доступе из нескольких потоков независимо от планирования или чередования выполнения этих потоков средой выполнения и без дополнительной синхронизации или другой координации со стороны вызывающего код.
Если поток изменяет значение экземпляра, измененное значение доступно для всех потоков, и только один поток может изменять значение за раз.
atomic
:если переменная экземпляра будет доступна в многопоточной среде.
atomic
:Не так быстро, как nonatomic
, потому что nonatomic
не требует каких-либо действий сторожевого таймера с момента выполнения.
nonatomic
:Если переменная экземпляра не будет изменена несколькими потоками, вы можете ее использовать. Это улучшает производительность.
Я нашел довольно хорошее объяснение атомных и неатомных свойств здесь. Вот какой-то соответствующий текст из этого же:
"атомный" означает, что он не может быть разбит. В терминах OS/программирования вызов атомной функции - это тот, который не может быть прерван - вся функция должна быть выполнена, а не выгружена из CPU обычным переключением контекста ОС до его завершения. На всякий случай вы не знали: поскольку процессор может делать только одно за раз, ОС вращает доступ к процессору ко всем работающим процессам в небольших временных срезах, чтобы создать иллюзию многозадачности. Планировщик ЦП может (и делает) прерывать процесс в любой момент его выполнения - даже в середине вызова функции. Поэтому для таких действий, как обновление общих счетных переменных, когда два процесса могут одновременно пытаться обновить переменную, они должны выполняться "атомарно", т.е. Каждое действие обновления должно заканчиваться целиком, прежде чем любой другой процесс можно поменять на ЦП.
Итак, я бы предположил, что атомарный в этом случае означает, что методы чтения атрибутов не могут быть прерваны - по сути это означает, что переменная (переменная), читаемая методом, не может изменить свое значение на полпути, потому что другой поток/вызов/function поменяется местами на CPU.
Поскольку переменные atomic
не могут быть прерваны, значение, содержащееся в них в любой точке, является гарантией , хотя, если эта блокировка потока делает доступ к ним помедленнее. non-atomic
переменные, с другой стороны, не дают такой гарантии, но предлагают роскошь более быстрого доступа. Чтобы подвести итог, перейдите с non-atomic
, когда вы знаете, что ваши переменные не будут доступны одновременно несколькими потоками и ускорить процесс.
После прочтения стольких статей, Stack переполнений и создания демонстрационных приложений для проверки атрибутов свойств переменной я решил собрать все данные атрибутов вместе:
atomic
//По умолчаниюnonatomic
strong = retain
//По умолчаниюweak = unsafe_unretained
retain
assign
//По умолчаниюunsafe_unretained
copy
readonly
readwrite
//По умолчаниюВ статье атрибуты свойства или модификаторы свойств в iOS вы можете найти все вышеупомянутые атрибуты, и это определенно поможет вам.
atomic
atomic
означает, что только один поток обращается к переменной (статический тип).atomic
является безопасным потоком.atomic
- поведение по умолчаниюПример:
@property (retain) NSString *name;
@synthesize name;
nonatomic
nonatomic
означает, что несколько потоков обращаются к переменной (динамический тип).nonatomic
является небезопасным.nonatomic
НЕ работает по умолчанию. Нам нужно добавить ключевое слово nonatomic
в атрибут свойства.Пример:
@property (nonatomic, retain) NSString *name;
@synthesize name;
Самый простой ответ: нет разницы между вашими вторыми двумя примерами. По умолчанию аксессоры свойств являются атомарными.
Атомарные аксессоры в среде, не содержащей мусор (т.е. при использовании сохранения/освобождения/авторекламы) будут использовать блокировку, чтобы гарантировать, что другой поток не мешает правильной установке/получении значения.
См. раздел " Производительность и потоки" в документации Apple Objective-C 2.0 для получения дополнительной информации и для другие соображения при создании многопоточных приложений.
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 является потокобезопасным, но он медленный.
Nonatomic означает, что несколько потоков обращаются к переменной (динамический тип). Nonatomic - небезопасный поток, но он быстро.
Atomic означает, что только один поток обращается к переменной (статический тип).
Пример:
@property (retain) NSString *name;
@synthesize name;
Nonatomic означает, что несколько потоков обращаются к переменной (динамический тип).
Пример:
@property (nonatomic, retain) NSString *name;
@synthesize name;
Объясняю:
Предположим, что существует свойство атомной строки, называемое "имя", и если вы вызываете [self setName: @ "A" ] из потока A,
Вызовите [self setName: @ "B" ] из потока B и вызовите [self name] из потока C, тогда все операции с другим потоком будут выполняться серийно, что означает, что если один поток выполняет setter или getter, тогда другие потоки будут ждать. Это делает свойство "имя" безопасным для чтения/записи, но если другой поток D вызывает [имя выпуска] одновременно, то эта операция может привести к сбою, потому что здесь нет вызова setter/getter. Это означает, что объект безопасен для чтения/записи (ATOMIC), но не является потокобезопасным, поскольку другие потоки могут одновременно отправлять сообщения любого типа в объект. Разработчик должен обеспечить безопасность потоков для таких объектов.
Если свойство "name" было неатомным, то все потоки в приведенном выше примере - A, B, C и D будут выполняться одновременно с получением любого непредсказуемого результата. В случае атома, сначала выполняется один из A, B или C, но D может выполняться параллельно. - Подробнее:
Теперь у нас есть еще несколько замечаний:
Атомный и неатомный относится к тому, будут ли сеттеры/геттеры для свойства атомарно читать и записывать значения в свойство. Когда ключевое слово атома используется для свойства, любой доступ к нему будет "синхронизирован". Поэтому при вызове геттера будет гарантировано возвращать действительное значение, однако это происходит с небольшим штрафом за производительность. Следовательно, в некоторых ситуациях неатомический используется для обеспечения более быстрого доступа к свойству, но есть вероятность того, что условие гонки приведет к тому, что свойство окажется равным нулю при редких обстоятельствах (когда значение задается из другого потока, а старое значение было выпущено из памяти, но новое значение еще не было полностью привязано к местоположению в памяти для свойства).
Atomic потокобезопасен, он медленный, и он обеспечивает (не гарантируется), что предоставляется только заблокированное значение независимо от того, сколько потоков пытается получить доступ к одной и той же зоне. При использовании атома кусок кода, написанный внутри этой функции, становится частью критического раздела, к которому может выполняться только один поток за раз.
Это только гарантирует безопасность потока; это не гарантирует этого. Я имею в виду, что вы нанимаете опытного водителя для своей машины, но это не гарантирует, что автомобиль не встретит аварии. Однако вероятность остается малейшей.
Atomic - его нельзя разбить, поэтому ожидается результат. С неатомным - когда другой поток обращается к зоне памяти, он может изменить его, поэтому результат неожиданно.
Обсуждение кода:
Atomic make getter и setter потока свойств безопасен. например, если u написано:
self.myProperty = value;
является потокобезопасным.
[myArray addObject:@"Abc"]
НЕ является потокобезопасным.
Нет такого ключевого слова "atomic"
@property(atomic, retain) UITextField *userName;
Мы можем использовать выше, как
@property(retain) UITextField *userName;
См. вопрос Я получаю проблемы, если я использую @property (атомный, сохраняю) NSString * myString.
по умолчанию - atomic
, это означает, что он будет стоить вам производительности, когда вы используете это свойство, но это потокобезопасно. Что делает Objective-C, устанавливается блокировка, так что только фактический поток может получить доступ к переменной, если выполняется setter/getter.
Пример с 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. Но если вы используете сеттер, и после этого геттер одновременно с двумя разными потоками, он тоже может быть сломан!
atomic (по умолчанию)
Atomic по умолчанию: если вы ничего не набираете, ваше свойство атомное. Атомное свойство гарантируется, что если вы попытаетесь прочитать он вернет действительное значение. Он не дает никаких гарантий о том, что это за значение, но вы вернете хорошие данные, а не просто мусорная память. Это позволяет вам сделать это, если у вас есть несколько потоков или нескольких процессов, указывающих на одну переменную, одну поток может читать, а другой поток может писать. Если они попадут в то же самое время чтения нити гарантированно получат одно из двух значений: либо до изменения, либо после изменения. Что атомное не дать вам любую гарантию о том, какие из этих ценностей вы может стать. Atomic действительно часто путают с потокобезопасностью, и это неверно. Вам необходимо гарантировать безопасность потока другими способами. Однако атомный будет гарантировать, что если вы попытаетесь прочитать, вы возвращаете какую-то ценность.
неатомической
С другой стороны, неатомный, как вы можете догадаться, просто означает, "Не делай этого атомного материала". То, что вы теряете, является гарантией того, что вы всегда возвращай что-то. Если вы попытаетесь прочитать в середине напишите, вы можете вернуть данные мусора. Но, с другой стороны, вы идете немного быстрее. Потому что атомарные свойства должны делать какую-то магию чтобы вы вернули стоимость, они немного медленнее. Если это свойство, к которому вы обращаетесь много, вы можете отказаться вниз до неатомического, чтобы убедиться, что вы не выполняете эту скорость штраф.
Подробнее здесь: https://realm.io/news/tmi-objective-c-property-attributes/
Как объявить:
Как атомный по умолчанию, поэтому,
@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,
Теперь Если свойство name неатомное, то
Вот почему не атомный называется потоком небезопасным Но, но он быстро работает из-за параллельного выполнения
Теперь If * свойство name является атомарным
То, почему атом называется thread Safe и Что называется безопасным для чтения и записи
Такая ситуационная операция будет выполняться серийно. И медленная производительность
- Nonatomic означает, что несколько потоков обращаются к переменной (динамический тип).
- неатомный поток небезопасен.
- но он быстро работает
-Nonatomic не является поведением по умолчанию, нам нужно добавить неатомическое ключевое слово в атрибуте свойства.
Для Быстрого Подтверждая, что свойства Swift неатомичны в смысле ObjC. Одна из причин заключается в том, что вы думаете о том, достаточно ли атомарности для каждой из ваших потребностей.
Ссылка: https://forums.developer.apple.com/thread/25642
Fro больше информации, пожалуйста, посетите веб-сайт http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html
atomic
НЕ поточно-! Он более устойчив к проблемам с потоками, но не безопасен для потоков. Это просто гарантирует, что вы получите целое значение, то есть «правильное» значение (двоичный уровень), но ни в коем случае не гарантирует, что это текущее и «правильное» значение для вашей бизнес-логики (это может быть прошлое значение и недействительным по вашей логике).
Прежде чем обсуждать атрибуты @property, вы должны знать, что такое использование @property. @property предлагает способ определения информации, которую класс должен инкапсулировать. Если вы объявляете объект/переменную с помощью @property, то этот объект/переменная будет доступен для других классов, импортирующих его класс. Если вы объявляете объект с использованием @property в файле заголовка, вам необходимо его синтезировать с помощью @synthesize в файле реализации.
Пример:
.h class
@interface ExampleClass : NSObject
@property (nonatomic, retain) NSString *name;
@end
.m class
@implementation ExampleClass
@synthesize name;
@end
Теперь компилятор будет синтезировать методы доступа для имени.
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
nonatomic: он не является потокобезопасным. Вы можете использовать атрибут nonatomic property, чтобы указать, что синтезированные аксессоры просто устанавливают или возвращают значение напрямую, без каких-либо гарантий относительно того, что произойдет, если одно и то же значение будет доступно одновременно из разных потоков. По этой причине он быстрее получает доступ к неатомическому свойству, чем к атомному.
@property (nonatomic)NSString *name;
Сохранить: требуется, когда атрибут является указателем на объект. Метод setter увеличит количество удержаний объекта, чтобы он занимал память в пуле автозапуска.
@property (retain)NSString *name;
copy: если вы используете копию, вы не можете использовать сохранение. Использование экземпляра копии класса будет содержать свою собственную копию. Даже если измененная строка установлена и впоследствии изменена, экземпляр фиксирует любое значение, которое он имеет в момент его установки. Никакие методы сеттера и геттера не будут синтезированы.
@property (copy) NSString *name;
NSMutableString *nameString = [NSMutableString stringWithString:@"Liza"];
xyzObj.name = nameString;
[nameString appendString:@"Pizza"];
readonly: Если вы не хотите, чтобы свойство было изменено с помощью метода setter, вы можете объявить свойство readonly.
@property (readonly) NSString *name;
readwrite: это поведение по умолчанию. Вам не нужно явно указывать атрибут readwrite.
@property (readwrite) NSString *name;
assign: сгенерирует сеттер, который напрямую присваивает значение переменной экземпляра, а не копирует или сохраняет его. Это лучше всего подходит для таких примитивных типов, как NSInteger и CGFloat, или объектов, которые вы не являетесь непосредственно, например делегатов.
@property (assign) NSInteger year;
strong: это замена для сохранения.
@property (nonatomic, strong) AVPlayer *player;
unsafe_unretained: Есть несколько классов в Cocoa и Cocoa Touch, которые еще не поддерживают слабые ссылки, а это означает, что вы не можете объявить слабое свойство или слабую локальную переменную, чтобы отслеживать их. Эти классы включают NSTextView, NSFont и NSColorSpace и т.д. Если вам нужно использовать слабую ссылку на один из этих классов, вы должны использовать небезопасную ссылку. Небезопасная ссылка похожа на слабую ссылку на то, что она не поддерживает связанный с ней объект, но он не будет установлен в нуль, если объект назначения будет освобожден.
@property (unsafe_unretained) NSObject *unsafeProperty;
Если вы используете свое свойство в многопоточном коде, вы сможете увидеть разницу между неатомическими и атомными атрибутами. Неатомный быстрее, чем атомный, а атомный - поточно-безопасный, а не неатомный.
Vijayendra Tripathi уже привел пример для многопоточной среды.
Прежде чем начать: вы должны знать, что каждый объект в памяти должен быть освобожден из памяти для новой записи. Вы не можете просто писать поверх чего-то, как на бумаге. Вы должны сначала стереть (dealloc), а затем вы можете записать на него. Если в тот момент, когда стирание выполнено (или сделано наполовину) и ничего еще не написано (или написано наполовину), и вы пытаетесь его прочитать, это может быть очень проблематично! Атомная и неатомическая помощь по-разному обрабатывает эту проблему.
Сначала прочитайте этот вопрос, а затем прочитайте ответ Bbum. Кроме того, прочитайте мое резюме.
atomic
ВСЕГДА будет гарантировать
Сохранение счетчиков - это способ управления памятью в Objective-C. Когда вы создаете объект, он имеет счет сохранения 1. Когда вы отправляете объект сохраняет сообщение, его счетчик удержания увеличивается на 1. Когда вы отправляете объекту сообщение о выпуске, его количество удержания уменьшается 1. Когда вы отправляете объект сообщение автореферата, его счетчик сохранения уменьшается на 1 на определенном этапе в будущем. Если объект сохраняется count уменьшается до 0, оно освобождается.
Подождите, что?! Многопоточность и безопасность потоков отличаются?
Да. Многопоточность означает: несколько потоков могут одновременно считывать общую часть данных, и мы не будем аварийно завершать работу, но это не гарантирует, что вы не читаете значение, не поддерживаемое автореализацией. Благодаря безопасности потока гарантируется, что то, что вы читаете, не будет автоматически выпущено. Причина, по которой мы не делаем все атомарным по умолчанию, - это потому, что есть стоимость исполнения, и для большинства вещей на самом деле не нужна безопасность потоков. Для этого нужны несколько частей нашего кода, и для этих нескольких частей нам нужно написать наш код в потоковом режиме с помощью блокировок, мьютексов или синхронизации.
nonatomic
В целом они различаются по двум аспектам:
Сбой или нет из-за наличия или отсутствия пула авторасчетов.
Позволяет читать прямо посередине "еще не законченного записи или пустого значения" или не разрешать и разрешать чтение только после полной записи значения.
Атомное свойство гарантирует сохранение полностью инициализированного значения независимо от того, сколько потоков работает на нем.
Неатомическое свойство указывает, что синтезированные аксессоры просто устанавливают или возвращают значение напрямую, без каких-либо гарантий относительно того, что произойдет, если одно и то же значение будет доступно одновременно из разных потоков.
Atomic означает, что только один поток может получить доступ к переменной за раз (статический тип). Atomic является потокобезопасным, но он медленный.
Nonatomic означает, что несколько потоков могут одновременно обращаться к переменной (динамический тип). Nonatomic - небезопасный поток, но он быстро.
Если вы используете атомный, это означает, что поток будет безопасным и доступным только для чтения. Если вы используете неатомический, это означает, что несколько потоков обращаются к переменной и являются небезопасными, но выполняются быстро, выполняются операции чтения и записи; это динамический тип.
Атомарность атомная (по умолчанию)
По умолчанию используется Atomic: если вы ничего не вводите, ваше свойство является атомарным. Атомарное свойство гарантировано, что если вы попытаетесь прочитать из него, вы получите верное значение. Это не дает никаких гарантий относительно того, каким может быть это значение, но вы получите хорошие данные, а не только ненужную память. Это позволяет вам делать, если у вас есть несколько потоков или несколько процессов, указывающих на одну переменную, один поток может читать, а другой поток может писать. Если они попадают в одно и то же время, поток чтения гарантированно получит одно из двух значений: либо до изменения, либо после изменения. То, что не дает вам атомарность, это какая-то гарантия того, какие из этих ценностей вы можете получить. Atomic обычно путают с поточностью потоков, и это не правильно. Вы должны гарантировать безопасность вашей нити другими способами. Тем не менее, Atomic гарантирует, что если вы попытаетесь читать, вы получите какое-то значение.
неатомической
С другой стороны, неатомарное, как вы, вероятно, можете догадаться, просто означает "не делайте этого атомарного материала". То, что вы теряете, - это гарантия того, что вы всегда что-то получите. Если вы попытаетесь прочитать в середине записи, вы можете получить обратно данные мусора. Но, с другой стороны, вы идете немного быстрее. Поскольку атомарные свойства должны творить чудеса, чтобы гарантировать возвращение значения, они немного медленнее. Если это свойство, к которому вы часто обращаетесь, вы можете перейти к неатомному, чтобы убедиться, что вы не понесете этот штраф за скорость. Доступ
Вежливость https://academy.realm.io/posts/tmi-objective-c-property-attributes/
Атрибуты свойств атомарности (атомарные и неатомарные) не отражены в соответствующем объявлении свойства Swift, но гарантии атомарности реализации Objective-C все еще сохраняются, когда к импортированному свойству обращаются из Swift.
Итак, если вы определите атомарное свойство в Objective-C, оно останется атомарным при использовании Swift.
вежливость https://medium.com/@YogevSitton/atomic-vs-non-atomic-properties-crash-course-d11c23f4366c
Атомарные свойства: - Когда переменная, назначенная с атомарным свойством, которое означает, что она имеет доступ только к одному потоку и будет поточно-ориентированной и будет хорошей с точки зрения производительности, будет иметь поведение по умолчанию.
Неатомарные свойства: - Когда переменная, назначенная с атомарным свойством, которое означает, что она имеет многопоточный доступ и не будет потокобезопасной, будет медленной с точки зрения производительности, будет иметь поведение по умолчанию и когда два разных потока захотят получить доступ к переменной одновременно это даст неожиданные результаты.
Atomic (по умолчанию) Atomic по умолчанию: если вы ничего не набираете, ваше свойство является атомарным. Атомное свойство гарантируется, что если вы попытаетесь прочитать его, вы вернете действительное значение. Он не дает никаких гарантий относительно того, что это может быть, но вы получите хорошие данные, а не только нежелательную память. Это позволяет вам сделать это, если у вас есть несколько потоков или несколько процессов, указывающих на одну переменную, один поток может читать, а другой поток может писать. Если они попадают одновременно, читательский поток гарантированно получит одно из двух значений: либо до изменения, либо после изменения. Что атомный не дает вам, это какая-то гарантия того, какие из этих значений вы можете получить. Atomic действительно часто путают с потокобезопасностью, и это неверно. Вам необходимо гарантировать, что ваши потоки безопасны другими способами. Однако атомный будет гарантировать, что если вы попытаетесь прочитать, вы получите какую-то ценность.
неатомической С другой стороны, неатомные, как вы можете догадаться, просто означают: "Не делайте этого атомного материала". То, что вы теряете, - это гарантия того, что вы всегда что-то возвращаете. Если вы попытаетесь прочитать в середине записи, вы можете вернуть данные мусора. Но, с другой стороны, вы идете немного быстрее. Поскольку свойства атома должны делать какую-то магию, чтобы гарантировать, что вы вернете значение, они немного медленнее. Если это свойство, к которому вы обращаетесь много, вам может потребоваться спуститься до неатомического, чтобы убедиться, что вы не выполняете это ограничение скорости.
Atomic
- поведение по умолчанию будет гарантировать, что текущий процесс будет завершен ЦП, прежде чем другой процесс обратится к переменной не быстро, так как он полностью завершает процесс
неатомарная
НЕ является поведением по умолчанию быстрее (для синтезированного кода, то есть для переменных, созданных с использованием @property и @synthesize) небезопасный может привести к неожиданному поведению, когда два разных процесса доступа к одной и той же переменной в то же время
Истина заключается в том, что они используют блокировку спина для реализации атомного свойства. Код, как показано ниже:
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);
}
Чтобы упростить всю путаницу, давайте разберемся с блокировкой мьютекса.
Блокировка мьютекса в соответствии с именем блокирует изменчивость объекта. Таким образом, если к объекту обращается класс, никакой другой класс не может получить доступ к тому же объекту.
В iOS @sychronise
также обеспечивает блокировку мьютекса. Теперь он работает в режиме FIFO и гарантирует, что на поток не влияют два класса, совместно использующие один и тот же экземпляр. Однако, если задача находится в главном потоке, избегайте доступа к объекту с использованием атомарных свойств, так как это может задержать ваш пользовательский интерфейс и снизить производительность.
Atomic: Обеспечьте безопасность потока, заблокировав поток с помощью NSLOCK.
Non atomic: не обеспечивает безопасность потока, поскольку механизм фиксации нити отсутствует.