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

Что atomicи nonatomicозначает в декларациях собственности?

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

В чем заключается оперативная разница между этими тремя?

26.02.2009 02:31:34
26 ОТВЕТОВ
РЕШЕНИЕ

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

Предполагая, что вы @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пока зависимые свойства обновляются.

1759
28.03.2017 16:52:14
Учитывая, что любой потокобезопасный код будет выполнять свою собственную блокировку и т. Д., Когда вы захотите использовать методы доступа к атомарным свойствам? У меня проблемы с придумыванием хорошего примера.
Daniel Dickison 24.05.2011 20:00:41
@bbum имеет смысл. Мне нравится ваш комментарий к другому ответу, что безопасность потоков - это скорее проблема на уровне модели. Из определения безопасности потока IBM: ibm.co/yTEbjY "Если класс реализован правильно, это еще один способ сказать, что он соответствует его спецификации, никакой последовательности операций (чтение или запись открытых полей и вызовы открытых методов) на объектах этого класса должна быть возможность поместить объект в недопустимое состояние, наблюдать, как объект находится в недопустимом состоянии, или нарушать любые инварианты, предусловия или постусловия класса ».
Ben Flynn 26.01.2012 19:22:53
Вот пример, похожий на @StevenKramer's: у меня есть @property NSArray* astronomicalEvents;список данных, которые я хочу отобразить в пользовательском интерфейсе. Когда приложение запускает указатель, указывающий на пустой массив, приложение извлекает данные из Интернета. Когда веб-запрос завершается (в другом потоке), приложение создает новый массив, а затем атомарно присваивает свойству новое значение указателя. Это потокобезопасно, и мне не нужно было писать код блокировки, если я что-то упустил. Кажется довольно полезным для меня.
bugloaf 15.02.2013 15:52:30
@HotLicks Еще один забавный; на некоторых архитектурах (не помню, какая именно) 64-битные значения, передаваемые в качестве аргумента, могут передаваться наполовину в регистре и наполовину в стеке. atomicпредотвращает перекрестное чтение половинных значений. (Это была забавная ошибка, чтобы выследить.)
bbum 23.11.2013 23:19:41
@congliu Тема A возвращает объект без retain/autoreleaseтанца. Поток B освобождает объект. Нить А идет бум . atomicгарантирует, что поток A имеет сильную ссылку (число сохранений +1) для возвращаемого значения.
bbum 6.12.2013 07:13:36

Атомный:

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

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

-(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, он не гарантирует, что каждый раз полностью инициализированный объект возвращается.

Плюсы: чрезвычайно быстрое исполнение.

Минусы: вероятность получения мусора в случае многопоточности.

54
17.07.2016 22:32:12
Этот комментарий не имеет большого смысла. Вы можете уточнить? Если вы посмотрите на примеры на сайте Apple, то ключевое слово atomic синхронизируется с объектом при обновлении его свойств.
Andrew Grant 26.02.2009 07:31:31

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

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

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

52
15.03.2013 05:34:24
Две причины Прежде всего, для синтезированного кода он генерирует быстрее (но не потокобезопасный код). Во-вторых, если вы пишете клиентские средства доступа, которые не являются атомарными, это позволяет вам для любого будущего пользователя комментировать, что код не является атомарным, когда они читают его интерфейс, не делая их реализацию.
Louis Gerbarg 26.02.2009 06:34:41

Это объясняется в документации Apple , но ниже приведены некоторые примеры того, что на самом деле происходит.

Обратите внимание, что ключевое слово «atomic» отсутствует, если вы не укажете «nonatomic», свойство будет атомарным, но если явно указать «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.

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

359
18.09.2019 14:16:55
@Louis Gerbarg: Я полагаю, что ваша версия (неатомного, сохраняющего) сеттера не будет работать должным образом, если вы попытаетесь назначить один и тот же объект (то есть: userName == userName_)
Florin 12.08.2010 09:29:41
Ваш код немного вводит в заблуждение; нет нет гарантии на то , что атомные добытчики / сеттера синхронизированы. Критически, @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/…
tc. 1.12.2010 18:20:56
@fyolnish Я не уверен, что _val/ valесть, но нет, не совсем. Метод получения атомарного свойства copy/ retainсвойства должен убедиться, что он не возвращает объект, чей refcount становится равным нулю из-за того, что метод вызова вызывается в другом потоке, что по сути означает, что ему нужно прочитать ивар, сохранить его и убедиться, что он не имеет перезаписать и отпустить его, а затем автоматически выпустить, чтобы сбалансировать сохранение. По сути, это означает, что и получатель, и установщик должны использовать блокировку (если структура памяти была исправлена, это должно быть осуществимо с помощью инструкций CAS2; увы -retain, это вызов метода).
tc. 10.12.2013 11:09:34
@tc Прошло довольно много времени, но я хотел написать следующее: gist.github.com/fjolnir/5d96b3272c6255f6baae Но да, старое значение может быть прочитано читателем перед возвращением setFoo: и выпущено до читатель возвращает это. Но, возможно, если бы сеттер использовал -autorelease вместо -release, это бы исправило это.
Fjölnir 11.12.2013 05:47:41
@fyolnish К сожалению, нет: это автоматически выпускает в потоке установщика, в то время как это должно быть автоматически выпущено в потоке получателя. Кроме того, похоже, что есть (небольшой) шанс исчерпания стека, потому что вы используете рекурсию.
tc. 11.12.2013 13:18:15

Там нет такого ключевого слова "атомная"

@property(atomic, retain) UITextField *userName;

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

@property(retain) UITextField *userName;

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

13
23.05.2017 11:33:24
«Существует такое ключевое слово», что ключевое слово не требуется по умолчанию и даже является значением по умолчанию, не означает, что ключевое слово не существует.
Matthijn 25.02.2013 14:51:17
Это неверно Ключевое слово существует. Этот ответ вводит в заблуждение, и я бы посоветовал снять его.
sethfri 20.05.2015 00:00:42

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

Предположим, что есть атомарное строковое свойство с именем «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 все еще может выполняться параллельно.

136
31.01.2016 10:02:03

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

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

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

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

69
17.06.2014 05:39:03
Ссылка не работает. ; (
Rob 10.03.2019 16:25:54
Это проблема со ссылками :( К счастью, я процитировал соответствующий текст в своем ответе
tipycalFlow 9.03.2020 07:35:49

атомное

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

Неатомарный

  • НЕ по умолчанию
  • быстрее (для синтезированного кода, то есть для переменных, созданных с использованием @property и @synthesize)
  • не потокобезопасный
  • может привести к непредвиденному поведению, когда два разных процесса одновременно обращаются к одной и той же переменной
168
31.01.2016 10:03:47

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

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

Я всегда считал атомную по умолчанию довольно любопытной. На уровне абстракции, над которым мы работаем, использование атомарных свойств для класса в качестве транспортного средства для достижения 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геттера в неоспоримых случаях (значения в секундах):

  • MRC | неатомный | Внедренные вручную геттеры
  • MRC | неатомный | синтезированный геттер: 7
  • MRC | атомный | синтезированный геттер: 47
  • ARC | неатомный | синтезированный геттер: 38 (примечание: ARC добавляет количество циклов отсчета здесь)
  • ARC | атомный | синтезированный геттер: 47

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

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

114
17.10.2019 03:07:27
MRC | атомный | синтезированный геттер: 47 ARC | атомный | синтезированный геттер: 47 Что делает их одинаковыми? Разве у ARC не должно быть больше накладных расходов?
SDEZero 27.08.2012 15:20:46
Так что, если атомные свойства плохи, они по умолчанию. Чтобы увеличить шаблон кода?
Kunal Balani 17.09.2013 20:44:59
@ LearnCocos2D Я только что протестировал 10.8.5 на той же машине, нацеливаясь на 10.8, для однопоточного неоспоримого случая с 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.
justin 23.09.2013 13:34:05
у вас есть этот тест онлайн где-нибудь? Я продолжаю добавлять свои здесь: github.com/LearnCocos2D/LearnCocos2D/tree/master/…
LearnCocos2D 23.09.2013 14:09:57
@ LearnCocos2D Я не приготовил их для потребления человеком, извините.
justin 23.09.2013 17:13:50

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

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

31
31.01.2016 10:09:56

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

  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;
67
31.01.2016 10:22:24
Как назначить и сильный / сохранить оба по умолчанию?
BangOperator 29.07.2016 16:06:14
Сильный приходит с ARC, сохранение было по умолчанию до ARC
abdullahselek 5.04.2017 13:21:24

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

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

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

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

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

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

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

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

Смысл atomic:

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

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

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

95
31.01.2016 13:57:20
Все, что вы здесь говорите, верно, но последнее предложение, по сути, «неправильно», Дура, для сегодняшнего программирования. Это действительно невероятно, что вы попытаетесь «улучшить производительность» таким способом. (Я имею в виду, что до того, как вы доберетесь до этого через несколько лет, вы бы «не использовали ARC», «не использовали NSString, потому что он медленный!» И т. Д.) Чтобы привести крайний пример, это все равно, что сказать «команда, не помещайте никаких комментариев в код, поскольку это замедляет нас. " Не существует реалистичного конвейера разработки, где бы вы хотели (несуществующего) теоретического прироста производительности ради ненадежности.
Fattie 1.06.2014 08:37:19
@JoeBlow это факт, вы можете проверить это здесь developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…
Durai Amuthan.H 1.06.2014 13:47:24
Durai, FWIW, эта ссылка прямо противоречит вашему тезису «Атомность = безопасность потоков». В документе Apple прямо говорится: «Атомарность свойства не является синонимом безопасности потока объекта». На практике атомарного редко бывает достаточно для обеспечения безопасности потока.
Rob 10.03.2020 15:42:36

По умолчанию является 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;

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

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

11
27.09.2013 09:43:38

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

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

9
31.01.2016 17:39:04

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

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

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

Code Talk:

Атомный make getter и setter свойства thread безопасны. например, если вы написали:

self.myProperty = value;

Поток безопасен.

[myArray addObject:@"Abc"] 

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

14
2.08.2017 09:43:33
Я не знаю, как получается последний абзац, но это просто неправильно, такого понятия, как «частная копия», не существует.
peak 26.11.2016 05:02:08

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

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

5
10.07.2016 14:15:51

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

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

3
10.07.2016 14:16:37

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

1
10.07.2016 14:18:07

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

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


atomic ВСЕГДА гарантируем

  • Если два разных человека хотят читать и писать одновременно, ваша газета не просто сгорит! -> Ваше приложение никогда не рухнет, даже в состоянии гонки.
  • Если один человек пытается написать и написал только 4 из 8 писем для записи, то не может читать в середине, чтение может быть выполнено только тогда, когда написаны все 8 букв -> Не читается (получит) произойдет «поток, который все еще пишет», т. е. если есть 8 байтов для байтов, которые должны быть записаны, и только 4 байта записаны - до этого момента вы не можете читать из него. Но так как я сказал, что он не будет аварийно завершать работу, он будет считывать значение из автоматически выпущенного объекта.
  • Если перед тем писать вы уже стерта , что ранее было написано на бумаге , а затем кто - то хочет читать вы можете еще прочитать. Как? Вы будете читать что-то похожее на мусорное ведро Mac OS (так как мусорное ведро еще не удалено на 100% ... оно находится в подвешенном состоянии) ---> Если ThreadA должен читать, а ThreadB уже освобожден для записи, вы получите значение из окончательного полностью записанного значения ThreadB или получение чего-либо из пула автоматического выпуска.

Сохранять счетчики - это способ управления памятью в Objective-C. Когда вы создаете объект, он имеет счет сохранения 1. Когда вы отправляете объекту сообщение сохранения, его счет хранения увеличивается на 1. Когда вы отправляете объекту сообщение об освобождении, его счет хранения уменьшается на 1. Когда вы отправьте объекту сообщение об автоматическом высвобождении , его количество сохранений будет уменьшено на 1 на каком-то этапе в будущем. Если количество сохраняемых объектов уменьшается до 0, оно освобождается.

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

Какая?! Отличаются ли многопоточность и безопасность потоков ?

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


nonatomic

  • Поскольку не существует такой вещи, как мусорное ведро Mac OS, то никого не волнует, всегда ли вы получаете значение (<- это может привести к сбою), и никому нет дела, если кто-то пытается прочитать в середине вашего письма (хотя наполовину запись в памяти сильно отличается от написания наполовину на бумаге, в памяти это может дать вам сумасшедшее глупое значение, в то время как на бумаге вы видите только половину написанного) -> Не гарантирует, что не произойдет сбой, потому что это не использует механизм автоматического выпуска.
  • Не гарантирует полного написания значений для чтения!
  • Быстрее атомного

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

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

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

10
17.06.2019 13:29:04

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

Не атомарный: не обеспечивает безопасность потока, так как нет механизма блокировки потока.

-1
10.07.2016 14:19:17

атомарный (по умолчанию)

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

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

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

Смотрите больше здесь: https://realm.io/news/tmi-objective-c-property-attributes/

12
23.07.2016 06:34:02

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

Блокировка мьютекса в соответствии с именем блокирует изменчивость объекта. Таким образом, если к объекту обращается класс, никакой другой класс не может получить доступ к тому же объекту.

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

0
14.12.2018 00:36:16

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

 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);
    }
1
9.12.2016 05:04:23
  • -Атомный означает, что только один поток обращается к переменной (статический тип).
  • -Атомный потокобезопасный.
  • - но это медленно в производительности

Как объявить:

Как атомная по умолчанию,

@property (retain) NSString *name;

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

self.name = @"sourov";

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

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

Все свойства работают параллельно (как асинхронно).

Если вы называете «имя» из потока А ,

А также

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

[self setName:@"Datta"]

из нити B ,

Теперь, если * name свойство неатомично, то

  • Вернет значение "Датта" для А
  • Он вернет значение "Датта" для B

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

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

  • Это обеспечит значение "Sourov" для A
  • Тогда он вернет значение "Датта" для B

Вот почему 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

9
5.10.2017 07:19:59
Как сказали многие другие многие maaaaany, НЕatomic является потокобезопасным! Он более устойчив к проблемам с потоками, но не безопасен для потоков. Это просто гарантирует, что вы получите целое значение, то есть «правильное» значение (двоичный уровень), но ни в коем случае не гарантирует, что это текущее и «правильное» значение для вашей бизнес-логики (это может быть прошлое значение и недействительным по вашей логике).
Alejandro Iván 15.02.2017 13:31:12

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

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

-1
4.08.2018 11:26:43

Атомарность атомная (по умолчанию)

По умолчанию используется атомарный: если вы ничего не печатаете, ваше свойство атомарное. Атомарное свойство гарантировано, что если вы попытаетесь прочитать из него, вы получите верное значение. Это не дает никаких гарантий относительно того, каким может быть это значение, но вы получите хорошие данные, а не только ненужную память. Это позволяет вам, если у вас есть несколько потоков или несколько процессов, указывающих на одну переменную, один поток может читать, а другой поток может писать. Если они попадают в одно и то же время, поток чтения гарантированно получит одно из двух значений: либо до изменения, либо после изменения. То, что не дает вам атомарность, это какая-то гарантия того, какие из этих ценностей вы можете получить. 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

6
1.07.2019 08:01:02