Какая разница между атомными и неатомическими атрибутами?

Что означают atomic и nonatomic в объявлениях свойств?

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

Какова операционная разница между этими тремя?

+1818
источник поделиться
30 ответов

Последние два идентичны; "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 при обновлении зависимых свойств.

+1742
источник

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

Обратите внимание, что ключевое слово "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.

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

+356
источник
другие ответы

Связанные вопросы


Похожие вопросы

Atomic

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

неатомарной

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

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

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

+133
источник

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

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

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

Выполнение

Хорошо. Первое, что я хотел бы прояснить, это то, что реализация блокировки определяется реализацией и абстрагируется. Луи использует @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 | неатомный | получаемые вручную геттеры: 2
  • MRC | неатомный | синтезированный геттер: 7
  • MRC | атомный | синтезированный геттер: 47
  • ARC | неатомный | Синтезированный геттер: 38 (примечание: ARC, добавляя отсчет циклов здесь)
  • ARC | атомный | синтезированный геттер: 47

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

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

+113
источник

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

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

Безопасность резьбы:

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

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

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

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

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

Вывод atomic:

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

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

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

+96
источник

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

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

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

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

+68
источник

После прочтения стольких статей, 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;
    
+66
источник

Атомный:

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

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

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

+54
источник

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

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

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

+52
источник

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

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

+32
источник

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

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

Пример:

@property (retain) NSString *name;

@synthesize name;

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

  • Nonatomic - небезопасный поток.
  • Но это быстро работает
  • 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 может выполняться параллельно. - Подробнее:

Теперь у нас есть еще несколько замечаний:

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

+15

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

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

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

Обсуждение кода:

Atomic make getter и setter потока свойств безопасен. например, если u написано:

self.myProperty = value;

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

[myArray addObject:@"Abc"] 

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

+15
источник

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

@property(atomic, retain) UITextField *userName;

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

@property(retain) UITextField *userName;

См. вопрос Я получаю проблемы, если я использую @property (атомный, сохраняю) NSString * myString.

+13
источник

по умолчанию - 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. Но если вы используете сеттер, и после этого геттер одновременно с двумя разными потоками, он тоже может быть сломан!

+11
источник

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

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

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

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

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

+11
источник

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

Vijayendra Tripathi уже привел пример для многопоточной среды.

+9
источник

Прежде чем обсуждать атрибуты @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;

+9
источник

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

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

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

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

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

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

@property (retain) NSString *name;

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

self.name = @"sourov";

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

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

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

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

И

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

[self setName:@"Datta"]

из потока B,

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

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

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

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

  • Это обеспечит значение "Суров" для A
  • Затем он вернет значение "Datta" для B

То, почему атом называется 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

+9
источник

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

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

+5
источник

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

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

+4
источник

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

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

+3
источник

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

+2
источник

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

 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
источник

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

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

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

0
источник

Atomic

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

неатомарная

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

0

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

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

0

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

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

0
источник

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

Non atomic: не обеспечивает безопасность потока, поскольку механизм фиксации нити отсутствует.

-1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос