В чем разница между атомарными и неатомарными атрибутами? - PullRequest
1796 голосов
/ 26 февраля 2009

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

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

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

Ответы [ 27 ]

31 голосов
/ 22 ноября 2012

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

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

14 голосов
/ 07 июля 2015

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

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

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

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

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

self.myProperty = value;

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

[myArray addObject:@"Abc"] 

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

12 голосов
/ 08 ноября 2011

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

@property(atomic, retain) UITextField *userName;

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

@property(retain) UITextField *userName;

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

11 голосов
/ 27 сентября 2013

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

Пример с MRC для свойства с иваром _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;

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

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

9 голосов
/ 18 июня 2015

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

Пример:

.ч класс

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

.m класс

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

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

copy: если вы используете copy, вы не можете использовать retain. Использование экземпляра экземпляра класса будет содержать собственную копию. Даже если изменяемая строка установлена ​​и впоследствии изменена, экземпляр захватывает любое значение, которое он имеет во время его установки. Методы получения и получения не будут синтезированы.

@property (copy) NSString *name;

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

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

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

@property (readwrite) NSString *name;

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

@property (assign) NSInteger year;

Сильный: замена для удержания. @property (nonatomic, strong) AVPlayer *player;

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

@property (unsafe_unretained) NSObject *unsafeProperty;

9 голосов
/ 23 июля 2016

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

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

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

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

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

8 голосов
/ 13 августа 2014

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

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

8 голосов
/ 13 декабря 2016
  • -Атомный означает, что только один поток обращается к переменной (статический тип).
  • -Атомный потокобезопасный.
  • - но это медленно работает

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

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

@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 ,

Now Если * свойство name неатомарное , тогда

  • Будет возвращено значение "Датта" для A
  • Будет возвращено значение "Датта" для B

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

Сейчас, если * свойство name является атомарным

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

Вот почему атомарность называется потокобезопасной и Именно поэтому он называется безопасным для чтения и записи

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

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

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

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

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

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

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

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

8 голосов
/ 28 апреля 2016

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

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


atomic ВСЕГДА будет гарантировать

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

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

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

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

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


nonatomic

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

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

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

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

4 голосов
/ 23 октября 2015

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

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

...