Что atomic
и nonatomic
означает в декларациях собственности?
@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;
В чем заключается оперативная разница между этими тремя?
ios
objective-c
properties
atomic
nonatomic
Алекс Уэйн
источник
источник
Ответы:
Последние два идентичны; «Атомное» является поведением по умолчанию (
обратите внимание, что на самом деле это не ключевое слово; оно определяется только отсутствием-nonatomic
atomic
было добавлено в качестве ключевого слова в последних версиях llvm / clang).Предполагая, что вы @synthesizing реализации метода, атомарный против неатомарного изменения сгенерированного кода. Если вы пишете свой собственный установщик / получатель, атомарный / неатомный / сохранить / назначить / копировать просто рекомендации. (Примечание: @synthesize теперь является поведением по умолчанию в последних версиях LLVM. Также нет необходимости объявлять переменные экземпляра; они также будут автоматически синтезироваться и иметь
_
префикс перед именем для предотвращения случайного прямого доступа).С «атомарным» синтезированный установщик / получатель будет гарантировать, что целое значение всегда возвращается из получателя или устанавливается установщиком, независимо от активности сеттера в любом другом потоке. То есть, если поток A находится в середине метода получения, а поток B вызывает метод установки, фактическое жизнеспособное значение - объект с автоматически выпускаемым кодом, скорее всего, - будет возвращено вызывающей стороне в A.
В
nonatomic
никаких таких гарантий не производятся. Таким образом,nonatomic
значительно быстрее, чем «атомный».То, что «атомарный» не делает, это делает какие-либо гарантии безопасности потоков. Если поток A вызывает метод получения одновременно, а поток B и C вызывают метод установки с различными значениями, поток A может получить любое одно из трех возвращенных значений - одно до вызова любого метода установки или любое из значений, переданных в методы установки в B и C. Аналогично, объект может в конечном итоге получить значение из B или C, что никак нельзя сказать.
Обеспечение целостности данных - одна из основных задач многопоточного программирования - достигается другими средствами.
Добавление к этому:
atomicity
одного свойства также не может гарантировать безопасность потока, когда в игре находятся несколько зависимых свойств.Рассматривать:
В этом случае поток A может переименовывать объект, вызывая
setFirstName:
и затем вызываяsetLastName:
. Между тем, поток B может вызыватьfullName
между двумя вызовами потока A и получит новое имя в сочетании со старой фамилией.Чтобы решить эту проблему, вам нужна транзакционная модель . Т.е. некоторый другой вид синхронизации и / или исключения, который позволяет исключить доступ,
fullName
пока зависимые свойства обновляются.источник
@property NSArray* astronomicalEvents;
список данных, которые я хочу отобразить в пользовательском интерфейсе. Когда приложение запускает указатель на пустой массив, приложение извлекает данные из Интернета. Когда веб-запрос завершается (в другом потоке), приложение создает новый массив, а затем атомарно присваивает свойству новое значение указателя. Это потокобезопасно, и мне не нужно было писать код блокировки, если я что-то упустил. Кажется довольно полезным для меня.atomic
предотвращает перекрестное чтение половинных значений. (Это была забавная ошибка, чтобы выследить.)retain/autorelease
танца. Поток B освобождает объект. Нить А идет бум .atomic
гарантирует, что поток A имеет сильную ссылку (число сохранений +1) для возвращаемого значения.Это объясняется в документации Apple , но ниже приведены некоторые примеры того, что на самом деле происходит.
Обратите внимание, что ключевое слово «atomic» отсутствует, если вы не укажете «nonatomic», тогда свойство является атомарным, но если явно указать «atomic», это приведет к ошибке.Если вы не укажете «nonatomic», тогда свойство будет атомарным, но вы все равно можете явно указать «atomic» в последних версиях, если хотите.
Теперь атомный вариант немного сложнее:
По сути, атомарная версия должна блокироваться, чтобы гарантировать безопасность потока, а также увеличивает счетчик ссылок на объект (и счет автоматического выпуска, чтобы сбалансировать его), так что объект гарантированно существует для вызывающей стороны, в противном случае является потенциальным условием гонки, если другой поток устанавливает значение, в результате чего счетчик ссылок падает до 0.
На самом деле существует большое количество различных вариантов того, как эти вещи работают, в зависимости от того, являются ли свойства скалярными значениями или объектами, и как взаимодействуют операции сохранения, копирования, чтения, неатома и т. Д. В общем, синтезаторы свойств просто знают, как сделать «правильную вещь» для всех комбинаций.
источник
@property (assign) id delegate;
не синхронизируется ни на чем (iOS SDK GCC 4.2 ARM-Os
), что означает гонку между[self.delegate delegateMethod:self];
иfoo.delegate = nil; self.foo = nil; [super dealloc];
. См. Stackoverflow.com/questions/917884/…_val
/val
есть, но нет, не совсем. Метод получения атомарного свойстваcopy
/retain
свойства должен гарантировать, что он не возвращает объект, чей refcount становится равным нулю из-за того, что метод вызова вызывается в другом потоке, что по сути означает, что он должен прочитать ivar, сохранить его, при этом убедившись, что метод установки не имеет перезаписать и отпустить его, а затем автоматически выпустить, чтобы сбалансировать сохранение. По сути, это означает, что и получатель, и установщик должны использовать блокировку (если структура памяти была исправлена, это должно быть осуществимо с помощью инструкций CAS2; увы-retain
, это вызов метода).атомное
Неатомарный
источник
Лучший способ понять разницу - использовать следующий пример.
Предположим, что есть атомарное строковое свойство с именем «name», и если вы вызываете
[self setName:@"A"]
из потока A, вызываете[self setName:@"B"]
из потока B и вызываете[self name]
из потока C, то все операции в разных потоках будут выполняться последовательно, что означает, что один поток выполняет установщик или получатель, тогда другие темы будут ждать.Это делает свойство «name» доступным для чтения / записи, но если другой поток, D, вызывает
[name release]
одновременно, то эта операция может привести к сбою, потому что здесь нет никакого вызова setter / getter. Это означает, что объект является безопасным для чтения / записи (ATOMIC), но не потокобезопасным, поскольку другие потоки могут одновременно отправлять объекту сообщения любого типа. Разработчик должен обеспечить безопасность потоков для таких объектов.Если свойство "name" было неатомичным, то все потоки в приведенном выше примере - A, B, C и D будут выполняться одновременно, что приведет к непредсказуемому результату. В случае атомарного, один из A, B или C будет выполняться первым, но D все еще может выполняться параллельно.
источник
Синтаксис и семантика уже хорошо определены другими превосходными ответами на этот вопрос. Поскольку исполнение и производительность не детализированы, я добавлю свой ответ.
Я всегда считал атомную по умолчанию довольно любопытной. На уровне абстракции, над которым мы работаем, использование атомарных свойств для класса в качестве транспортного средства для достижения 100% -ной безопасности потока является ключевым случаем. Для действительно правильных многопоточных программ вмешательство программиста почти наверняка является требованием. Между тем, характеристики производительности и исполнения еще не были подробно описаны. Написав несколько многопоточных программ за эти годы, я все время заявлял о своих свойствах,
nonatomic
потому что atomic не был пригоден для каких-либо целей. Во время обсуждения деталей атомных и неатомных свойств этого вопроса я при профилировании столкнулся с некоторыми любопытными результатами.выполнение
Хорошо. Первое, что я хотел бы прояснить, это то, что реализация блокировки определяется реализацией и абстрагируется. Луи использует
@synchronized(self)
в своем примере - я видел это как общий источник путаницы. Реализация на самом деле не использует@synchronized(self)
; он использует спин-блокировки на уровне объекта . Иллюстрация Луи хороша для иллюстрации высокого уровня с использованием конструкций, с которыми мы все знакомы, но важно знать, что она не используется@synchronized(self)
.Другое отличие состоит в том, что атомарные свойства будут сохранять / освобождать цикл ваших объектов в геттере.
Представление
Вот интересная часть: производительность, использующая доступ к элементарным свойствам в неоспоримых (например, однопоточных) случаях, в некоторых случаях может быть действительно очень высокой. В далеко не идеальных случаях использование атомарного доступа может стоить более чем в 20 раз дороже
nonatomic
. В случае оспариваемого случая, использующего 7 потоков, для трехбайтовой структуры было в 44 раза медленнее (2,2 ГГц Core i7 Quad Core, x86_64). Трехбайтовая структура является примером очень медленного свойства.Интересное примечание: определяемые пользователем средства доступа трехбайтовой структуры были в 52 раза быстрее, чем синтезированные атомарные средства доступа; или 84% скорости синтезированных неатомных акцессоров.
Объекты в оспариваемых случаях также могут превышать 50 раз.
Из-за большого количества оптимизаций и вариаций в реализации очень сложно измерить реальные воздействия в этих контекстах. Вы можете часто слышать что-то вроде «Доверяйте этому, если вы не профилируете и не обнаружите, что это проблема». Из-за уровня абстракции, на самом деле довольно сложно измерить фактическое влияние. Сбор фактических затрат из профилей может занять очень много времени, а из-за абстракций довольно неточен. Кроме того, ARC против MRC может иметь большое значение.
Итак, давайте сделаем шаг назад, не сосредотачиваясь на реализации доступа к свойствам, мы включим обычные подозреваемые, такие как
objc_msgSend
, и исследуем некоторые реальные результаты высокого уровня для многих вызововNSString
геттера в неоспоримом случаях (значения в секундах):Как вы, наверное, догадались, активность / циклический подсчет ссылок вносит существенный вклад в атомарность и в ARC. Вы также увидите большие различия в спорных случаях.
Хотя я уделяю пристальное внимание производительности, я по-прежнему говорю Semantics First! , Между тем, производительность является низким приоритетом для многих проектов. Однако знание деталей исполнения и стоимости используемых вами технологий, безусловно, не повредит. Вы должны использовать правильную технологию для ваших потребностей, целей и способностей. Надеемся, что это сэкономит вам несколько часов сравнений и поможет вам принять более обоснованное решение при разработке ваших программ.
источник
NSString
не бессмертным:-ARC atomic (BASELINE): 100% -ARC nonatomic, synthesised: 94% -ARC nonatomic, user defined: 86% -MRC nonatomic, user defined: 5% -MRC nonatomic, synthesised: 19% -MRC atomic: 102%
- результаты немного отличаются сегодня. Я не делал никаких@synchronized
сравнений.@synchronized
семантически отличается, и я не считаю его хорошим инструментом, если у вас нетривиальные параллельные программы. если вам нужна скорость, избегайте@synchronized
.Атомная = потокобезопасность
Неатомарный = нет безопасности потока
Безопасность потока:
Переменные экземпляра являются поточно-ориентированными, если они ведут себя корректно при доступе из нескольких потоков, независимо от планирования или чередования выполнения этих потоков средой выполнения, и без дополнительной синхронизации или другой координации со стороны вызывающего кода.
В нашем контексте:
Если поток изменяет значение экземпляра, измененное значение доступно всем потокам, и только один поток может изменить значение за раз.
Где использовать
atomic
:если переменная экземпляра будет доступна в многопоточной среде.
Смысл
atomic
:Не так быстро, как
nonatomic
потомуnonatomic
что не требует никакой сторожевой работы над этим из среды выполнения.Где использовать
nonatomic
:Если переменная экземпляра не будет изменена несколькими потоками, вы можете использовать ее. Это улучшает производительность.
источник
Я нашел довольно удачное объяснение атомных и неатомных свойств здесь . Вот некоторые соответствующие тексты из того же:
Поскольку
atomic
переменные не могут быть прерваны, значение, содержащееся в них в любой момент (поточечная блокировка), гарантированно не будет повреждено , хотя, гарантируя, что эта блокировка потока делает доступ к ним более медленным.non-atomic
Переменные, с другой стороны, не дают такой гарантии, но предлагают роскошь быстрого доступа. Подводя итог, пойдите,non-atomic
когда вы знаете, что ваши переменные не будут доступны для нескольких потоков одновременно, и ускорит процесс.источник
После прочтения очень многих статей, публикаций Stack Overflow и создания демонстрационных приложений для проверки атрибутов переменных свойств, я решил собрать всю информацию об атрибутах:
atomic
// По умолчаниюnonatomic
strong = retain
// По умолчаниюweak = unsafe_unretained
retain
assign
// По умолчаниюunsafe_unretained
copy
readonly
readwrite
// По умолчаниюВ статье Атрибуты свойств переменных или модификаторы в iOS вы можете найти все вышеупомянутые атрибуты, и это определенно вам поможет.
atomic
atomic
означает, что только один поток обращается к переменной (статический тип).atomic
Поток безопасен.atomic
поведение по умолчаниюПример:
nonatomic
nonatomic
означает многопоточный доступ к переменной (динамический тип).nonatomic
небезопасно.nonatomic
НЕ по умолчанию. Нам нужно добавитьnonatomic
ключевое слово в атрибуте свойства.Пример:
источник
Атомный:
Атомные гарантии, что доступ к собственности будет осуществляться атомарным способом. Например, он всегда возвращает полностью инициализированные объекты, любое получение / установка свойства в одном потоке должно завершиться, прежде чем другой сможет получить к нему доступ.
Если вы представите следующую функцию, выполняющуюся в двух потоках одновременно, вы поймете, почему результаты не будут хорошими.
Плюсы: возврат полностью инициализированных объектов каждый раз делает его лучшим выбором в случае многопоточности.
Минусы: производительность снижается, выполнение немного замедляется
Неатомный:
В отличие от Atomic, он не гарантирует, что каждый раз полностью инициализированный объект возвращается.
Плюсы: чрезвычайно быстрое исполнение.
Минусы: вероятность получения мусора в случае многопоточности.
источник
Самый простой ответ: нет разницы между вашими вторыми примерами. По умолчанию средства доступа к свойствам являются атомарными.
Атомарные методы доступа в среде без сборки мусора (т.е. при использовании retain / release / autorelease) будут использовать блокировку, чтобы гарантировать, что другой поток не будет мешать правильной установке / получению значения.
См. Раздел « Производительность и многопоточность » документации Apple Objective-C 2.0 для получения дополнительной информации и других соображений при создании многопоточных приложений.
источник
Атомный означает, что только один поток обращается к переменной (статический тип). Атомный потокобезопасный, но он медленный.
Неатомарный означает, что несколько потоков обращаются к переменной (динамический тип). Неатомный поток-небезопасный, но это быстро.
источник
Атомный потокобезопасен , он медленный и хорошо работает (не гарантируется) что предоставляется только заблокированное значение, независимо от того, сколько потоков пытается получить доступ через одну и ту же зону. При использовании atomic часть кода, написанная внутри этой функции, становится частью критической секции, в которую одновременно может работать только один поток.
Это только гарантирует безопасность потока; это не гарантирует этого. Я имею в виду, что вы нанимаете опытного водителя для своей машины, но это не гарантирует, что автомобиль не попадет в аварию. Однако вероятность остается малейшей.
Атомное - его нельзя сломать, поэтому результат ожидаем. С неатомарным - когда другой поток обращается к зоне памяти, он может изменить ее, поэтому результат будет неожиданным.
Code Talk:
Атомный make getter и setter свойства thread безопасны. например, если вы написали:
Поток безопасен.
НЕ является потокобезопасным.
источник
Там нет такого ключевого слова "атомная"
Мы можем использовать выше, как
См. Вопрос переполнения стека. У меня возникают проблемы, если я использую @property (atomic, retain) NSString * myString .
источник
Смотрите больше здесь: https://realm.io/news/tmi-objective-c-property-attributes/
источник
По умолчанию является
atomic
, это означает , что делает стоить вам производительность всякого раза , когда вы используете свойство, но это поточно. Что делает Objective-C, так это устанавливает блокировку, так что только фактический поток может получить доступ к переменной, пока выполняется установщик / получатель.Пример с MRC для свойства с ivar _internal:
Итак, последние два одинаковы:
С другой стороны, ничего не
nonatomic
добавляет к вашему коду. Так что это только потокобезопасно, если вы сами создадите механизм безопасности.Ключевые слова вообще не должны записываться как первый атрибут свойства.
Не забывайте, это не означает, что свойство в целом является потокобезопасным. Только вызов метода метода установки / получения. Но если вы используете сеттер, а затем одновременно геттер с двумя разными потоками, он тоже может быть поврежден!
источник
Прежде чем начать: Вы должны знать, что каждый объект в памяти должен быть освобожден из памяти, чтобы произошла новая запись. Вы не можете просто написать поверх чего-либо, как на бумаге. Вы должны сначала стереть (dealloc) это, а затем вы можете написать на него. Если в тот момент, когда стирание выполнено (или наполовину сделано) и ничего еще не написано (или наполовину написано), и вы попытаетесь прочитать, это может быть очень проблематично! Атомные и неатомные помогают вам по-разному относиться к этой проблеме.
Сначала прочитайте этот вопрос, а затем прочитайте ответ Bbum . Кроме того, тогда прочитайте мое резюме.
atomic
ВСЕГДА гарантируемКакая?! Отличаются ли многопоточность и безопасность потоков ?
Да. Многопоточность означает: несколько потоков могут одновременно читать общий фрагмент данных, и мы не будем аварийно завершать работу, но это не гарантирует, что вы не читаете из неавторизованного значения. С безопасностью потока гарантируется, что то, что вы читаете, не высвобождается автоматически. Причина, по которой мы не делаем все атомарным по умолчанию, заключается в том, что производительность снижается, и для большинства вещей действительно не требуется безопасность потоков. Несколько частей нашего кода нуждаются в этом, и для этих нескольких частей нам нужно написать наш код потокобезопасным способом, используя блокировки, мьютекс или синхронизацию.
nonatomic
В целом они отличаются в 2 аспектах:
Сбой или нет из-за наличия или отсутствия пула авто-релиза.
Позволяет читать прямо в середине «еще не законченной записи или пустого значения» или не разрешает и разрешает читать только тогда, когда значение полностью записано.
источник
Если вы используете свое свойство в многопоточном коде, вы сможете увидеть разницу между неатомарными и атомарными атрибутами. Неатомарное быстрее, чем атомное, а атомарное потокобезопасное, а не неатомарное.
Виджаендра Трипати уже привел пример многопоточной среды.
источник
Как объявить:
Как атомная по умолчанию,
И в файле реализации
Предположим, что задача, связанная с тремя свойствами
Все свойства работают параллельно (как асинхронно).
Если вы называете «имя» из потока А ,
А также
В то же время, если вы звоните
из нити B ,
Теперь, если * name свойство неатомично, то
Вот почему non atomic называется потоком небезопасным, но он быстрый по производительности из-за параллельного выполнения
Теперь, если * name свойство является атомарным
Вот почему Atomic называется потокобезопасным, и поэтому он называется безопасным для чтения и записи.
Такая ситуация операция будет выполнять поочередно. И медленно в исполнении
- Неатомный означает, что многопоточный доступ к переменной (динамический тип).
- Неатомный поток небезопасен.
- но это быстро в производительности
-Nonatomic не является поведением по умолчанию, нам нужно добавить ключевое слово nonatomic в атрибуте свойства.
Для In Swift Подтверждение того, что свойства Swift неатомичны в смысле ObjC. Одна из причин заключается в том, что вы думаете о том, достаточна ли атомарность для каждого объекта для ваших нужд.
Ссылка: https://forums.developer.apple.com/thread/25642
Для получения дополнительной информации посетите веб-сайт http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html.
источник
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 гарантирует сохранение полностью инициализированного значения независимо от того, сколько потоков выполняет для него getter & setter.
Неатомарное свойство указывает, что синтезированные методы доступа просто устанавливают или возвращают значение напрямую, без каких-либо гарантий относительно того, что произойдет, если к одному и тому же значению обращаются одновременно из разных потоков.
источник
Атомный означает, что только один поток может получить доступ к переменной одновременно (статический тип). Атомный потокобезопасный, но он медленный.
Неатомарный означает, что несколько потоков могут обращаться к переменной одновременно (динамический тип). Неатомный поток-небезопасный, но это быстро.
источник
Если вы используете атомарный, это означает, что поток будет безопасным и доступным только для чтения. Если вы используете nonatomic, это означает, что несколько потоков обращаются к переменной и являются потокобезопасными, но они выполняются быстро, выполняют операции чтения и записи; это динамический тип.
источник
Правда в том, что они используют спин-блокировку для реализации атомарного свойства. Код, как показано ниже:
источник
Чтобы упростить всю путаницу, давайте разберемся с блокировкой мьютекса.
Блокировка мьютекса в соответствии с именем блокирует изменчивость объекта. Таким образом, если к объекту обращается класс, никакой другой класс не может получить доступ к тому же объекту.
В iOS
@sychronise
также предусмотрена блокировка мьютекса. Теперь он работает в режиме FIFO и гарантирует, что на поток не влияют два класса, совместно использующие один и тот же экземпляр. Однако, если задача находится в главном потоке, избегайте доступа к объекту с использованием атомарных свойств, так как это может задержать ваш пользовательский интерфейс и снизить производительность.источник
Атомная: Обеспечить безопасность потока, заблокировав поток с помощью NSLOCK.
Не атомарный: не обеспечивает безопасность потока, так как нет механизма блокировки потока.
источник
Атомарные свойства : - Когда переменная, назначенная с атомарным свойством, которое означает, что она имеет доступ только к одному потоку и будет поточно-ориентированной и будет хорошей с точки зрения производительности, будет иметь поведение по умолчанию.
Неатомарные свойства : - Когда переменная, назначенная с атомарным свойством, которое означает, что она имеет многопоточный доступ и не будет потокобезопасной, будет медленной с точки зрения производительности, будет иметь поведение по умолчанию и когда два разных потока захотят получить доступ к переменной одновременно это даст неожиданные результаты.
источник