Что означают «атомные» и «неатомные» в декларациях собственности?
@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;
В чем разница между этими тремя?
Последние два идентичны; «атомный» - это поведение по умолчанию (< strike > обратите внимание, что это на самом деле не ключевое слово; оно указывается только отсутствием «нонатомический» < / strike > - «атомный» был добавлен в качестве ключевого слова в последние версии llvm / clang).
Предполагая, что вы @synthesizing реализации метода, атомный против. не атомарные изменения сгенерированного кода. Если вы пишете свой собственный сеттер / геттеры, атомная / неатомная / розничная / назначение / копирование являются просто консультативными. (Примечание: @synthesize теперь является поведением по умолчанию в последних версиях LLVM. Также нет необходимости объявлять переменные экземпляра; они также будут синтезированы автоматически и будут иметь _
с добавлением к своему имени для предотвращения случайного прямого доступа).
С «атомным» синтезированный сеттер / геттер гарантирует, что значение whole всегда возвращается из getter или устанавливается сеттером, независимо от активности сеттера в любом другом потоке. То есть, если поток A находится в середине getter, в то время как поток B вызывает установщик, фактическое жизнеспособное значение - скорее всего, объект с авторельефом - будет возвращено вызывающему абоненту в A .
В «неатомном» такие гарантии не предоставляются. Таким образом, «неатомный» значительно быстрее, чем «атомный».
То, что "атомный" делает не , делает какие-либо гарантии безопасности резьбы. Если поток A вызывает getter одновременно с потоками B и C, вызывая setter с разными значениями, поток A может получить любое из трех возвращаемых значений - одно до вызова любых установщиков или любое из значений, переданных установщикам в B и C. Аналогично, объект может в конечном итоге получить значение от B или C, нет способа сказать.
Обеспечение целостности данных - одна из основных задач многопоточного программирования - достигается другими способами.
Добавление к этому:
«атомность» одного свойства также не может гарантировать безопасность потока, когда в игре находятся несколько зависимых свойств.
Считать:
@property(atomic, copy) NSString *firstName;
@property(atomic, copy) NSString *lastName;
@property(readonly, atomic, copy) NSString *fullName;
В этом случае поток A может переименовывать объект, вызывая setFirstName:
, а затем вызываяsetLastName:
. В то же время, поток B может вызывать fullName
между двумя вызовами потока A и будет получать новое имя в сочетании со старой фамилией.
Для решения этой проблемы вам нужна транзакционная модель . Т.е. какой-то другой вид синхронизации и / или исключения, который позволяет исключить доступ к fullName
во время обновления зависимых свойств.
Это объясняется в [документации] Apple 1, но ниже приведены некоторые примеры того, что на самом деле происходит.
< strike > Обратите внимание, что не существует «атомного» ключевого слова, если вы не укажете «неатомный», то свойство будет атомным, но явное указание «атомного» приведет к ошибке.& Лт; / удар >Если вы не укажете «ненатомический», то свойство является атомным, но вы все равно можете указать «атомный» явно в последних версиях, если хотите.
//@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.
На самом деле существует большое количество различных вариантов того, как эти вещи работают, в зависимости от того, являются ли свойства скалярными значениями или объектами, и как взаимодействуют, копируют, читают, не атомарные и т. Д. В общем, синтезаторы свойств просто знают, как делать «правильные вещи» для всех комбинаций.
Лучший способ понять разницу - использовать следующий пример.
Предположим, что есть свойство атомной строки с именем &"имя и цитата; и если вы позвоните [self setName: @ &"A &"
из нити А, позвони [self setName: @ &"B &"
из нити B, и позвони [самоимя]
из нити С, тогда все операции на разных потоках будут выполняться последовательно, что означает, что один поток выполняет сеттер или геттер, тогда другие темы будут ждать.
Это делает свойство «name» read / write безопасным, но если другой поток, D, вызывает [name release]
одновременно, то эта операция может привести к сбою, поскольку здесь не задействован вызов setter / getter. Это означает, что объект безопасен для чтения / записи (ATOMIC), но не безопасен для потоков, поскольку другие потоки могут одновременно отправлять сообщения любого типа объекту. Разработчик должен обеспечить безопасность потоков для таких объектов.
Если свойство «name» было неатомным, то все потоки в приведенном выше примере - A, B, C и D будут выполняться одновременно, создавая любой непредсказуемый результат. В случае атома, один из A, B или C будет выполняться первым, но D все еще может выполняться параллельно.
Синтаксис и семантика уже четко определены другими отличными ответами на этот вопрос. Поскольку выполнение и производительность не очень хорошо детализированы, я добавлю свой ответ.
В чем функциональная разница между этими 3?
Я всегда считал атомным по умолчанию довольно любопытным. На уровне абстракции, над которым мы работаем, использование атомных свойств для класса в качестве средства достижения 100% безопасности резьбы является угловым примером. Для действительно правильных многопоточных программ вмешательство программиста почти наверняка является обязательным требованием. Между тем, характеристики производительности и исполнения не имеют # 160, но были подробно описаны. Написав несколько сильно многопоточных программ за эти годы, я все время объявлял свои свойства «неатомными», потому что атомная энергия не была разумной ни для каких целей. Во время обсуждения деталей атомных и неатомных свойств этот вопрос я сделал несколько профилирований, столкнувшихся с некоторыми любопытными результатами.
Казнь
Хорошо. Первое, что я хотел бы прояснить, это то, что реализация блокировки определяется реализацией и абстрагируется. Луи использует @ synchronized (self)
в своем примере - я видел это как общий источник путаницы. Реализация фактически не использует @ synchronized (self)
; он использует уровень объекта блокировки шпинделя . Иллюстрация Луи хороша для иллюстрации высокого уровня с использованием конструкций, с которыми мы все знакомы, но важно знать, что она не использует @ synchronized (self)
.
Другое отличие состоит в том, что атомные свойства сохранят / высвободят цикл ваших объектов в getter.
Производительность
Вот интересная часть: Производительность с использованием доступа к атомным свойствам в неоспоримо (например,. единичные) случаи могут быть очень быстрыми в некоторых случаях. В менее чем идеальных случаях использование атомных доступов может стоить более чем в 20 раз больше накладных расходов «неатомных». В то время как Оспариваемый случай с использованием 7 потоков был в 44 раза медленнее для трехбайтовой структуры (2,2 и nbsp; ГГц Core & nbsp; i7 Quad Core, x86_64). Трехбайтовая структура является примером очень медленного свойства.
Интересное примечание: пользовательские адаптеры трехбайтовой структуры были в 52 раза быстрее, чем синтезированные атомные аксессуары; или 84% скорость синтезированных неатомных ресекторов.
Объекты в оспариваемых случаях также могут превышать 50 раз.
Из-за ряда оптимизаций и различий в реализации довольно сложно измерить реальные воздействия в этих контекстах. Вы можете часто слышать что-то вроде «Доверяй этому, если не профилируешь и не обнаруживаешь, что это проблема». Из-за уровня абстракции на самом деле довольно сложно измерить фактическое влияние. Выделение фактических затрат из профилей может быть очень трудоемким, а из-за абстракций довольно неточным. Кроме того, ARC против MRC может иметь большое значение.
Итак, давайте сделаем шаг назад, не сосредоточившись на реализации доступа к собственности, мы включим обычных подозреваемых, таких как objc_msgSend
, и изучим некоторые результаты высокого уровня в реальном мире для многих вызовов getter NSString
в неоспоримых случаи (значения в секундах):
Как вы, наверное, догадались, активность / цикл подсчета ссылок вносит значительный вклад в атомики и в ARC. Вы также увидите большие различия в оспариваемых случаях.
Хотя я уделяю пристальное внимание производительности, я все же говорю Семантика в первую очередь!. Между тем, производительность является низким приоритетом для многих проектов. Однако знание деталей исполнения и стоимости технологий, которые вы используете, безусловно, не повредит. Вы должны использовать правильные технологии для своих нужд, целей и способностей. Надеемся, что это сэкономит вам несколько часов сравнений и поможет вам принять более обоснованное решение при разработке ваших программ.
Atomic = безопасность резьбы
Неатомный = Нет безопасности резьбы
Переменные экземпляра являются поточно-безопасными, если они ведут себя правильно при доступе из нескольких потоков, независимо от планирования или чередования выполнения этих потоков средой выполнения и без дополнительной синхронизации или другой координации со стороны вызывающего кода.
Если поток изменяет значение экземпляра, измененное значение доступно для всех потоков, и только один поток может изменять значение одновременно.
атомный
:если переменная экземпляра будет доступна в многопоточной среде.
атомного
:Не так быстро, как «неатомный», потому что «неатомный» не требует никакой сторожевой работы над этим во время выполнения .
nonatomic
:Если переменная экземпляра не будет изменена несколькими потоками, вы можете использовать ее. Это улучшает производительность.
Я нашел довольно хорошо сформулированное объяснение атомных и неатомных свойств [здесь](http://archive.atomicmpc.com.au/forums.asp?s = 2 & c = 10 & t = 4594). Вот некоторые соответствующие тексты из того же:
«атомный» означает, что его нельзя сломать. В терминах ОС / программирования вызов атомной функции не может быть прерван - вся функция должна быть выполнена, а не заменена процессором обычным переключением контекста ОС до его завершения. На всякий случай, если вы не знали: поскольку процессор может делать только одну вещь за раз, ОС вращает доступ к процессору ко всем запущенным процессам за небольшие промежутки времени, чтобы дать иллюзию многозадачности. Планировщик ЦП может (и делает) прерывать процесс в любой момент его выполнения - даже в середине вызова функции. Таким образом, для таких действий, как обновление общих встречных переменных, когда два процесса могут пытаться обновлять переменную одновременно, они должны выполняться «атомно», т.е.каждое действие обновления должно завершиться полностью, прежде чем любой другой процесс может быть заменен на процессор
Таким образом, я бы предположил, что атомная энергия в этом случае означает, что методы считывания атрибутов не могут быть прерваны - фактически это означает, что переменная (и), считываемая методом, не может изменить свое значение на полпути, потому что какой-то другой поток / вызов / функция переключается на процессор .
Поскольку «атомные» переменные не могут быть прерваны, значение, содержащееся в них в любой точке, (блокировка потока) гарантированно будет не поврежденным , хотя обеспечение этой блокировки потока делает доступ к ним медленнее. «неатомные» переменные, с другой стороны, не дают такой гарантии, но предлагают роскошь более быстрого доступа. Подводя итог, перейдите к «неатомному», когда вы знаете, что ваши переменные не будут доступны для нескольких потоков одновременно, и ускорите процесс.
Прочитав так много статей, Stack & nbsp; Переполнение постов и создание демонстрационных приложений для проверки атрибутов свойств переменных, я решил собрать всю информацию об атрибутах вместе:
atomic
// По умолчаниюstrong = сохранить
// По умолчаниюслабый = небезопасный_неудерживаемый
Retain
assign
// По умолчаниюunsafe_unretained
Копировать
readonly
readwrite
// По умолчаниюВ статье Переменные атрибуты или модификаторы свойств в iOS вы можете найти все вышеупомянутые атрибуты, и это определенно поможет вам.
атомный
Пример:
@property (retain) NSString * имя;
@synthesize имя;
nonatomic
nonatomic
в атрибут свойства.Пример:
@property (неатомный, сохранить) NSString * имя ;
@synthesize имя;
Атомные гарантии того, что доступ к объекту будет осуществляться атомным способом. Например. он всегда возвращает полностью инициализированные объекты, любой набор / набор свойства в одном потоке должен быть завершен, прежде чем другой сможет получить к нему доступ.
Если вы представляете следующую функцию, происходящую в двух потоках одновременно, вы можете понять, почему результаты не будут красивыми.
-(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, он не обеспечивает полное инициализированное возвращение объекта каждый раз.
Прос: Чрезвычайно быстрое выполнение.
Минусы: Шансы на мусор в случае многопоточности.
Самый простой ответ: нет разницы между вашими вторыми двумя примерами. По умолчанию доступ к свойствам является атомным.
Атомные аксессуары в не мусорной среде (т.е. при использовании фиксации / отпускания / автоматической аренды) будет использовать блокировку, чтобы гарантировать, что другой поток не помешает правильной настройке / получению значения.
См. Раздел «Производительность и порезка» документации Apple Objective-C 2.0 для получения дополнительной информации и других соображений при создании многопоточных приложений.
Атомный означает, что только один поток обращается к переменной (статический тип). Атомный безопасен для потоков, но медленный.
Нонатомический означает, что к переменной обращается несколько потоков (динамический тип). Нонатомический неэфирный, но быстрый.
Атомная безопасна для протектора , она медленная , и она вполне гарантирует (не гарантируется) , что предоставляется только заблокированное значение независимо от того, сколько потоков пытаются получить доступ через одну и ту же зону. При использовании атома фрагмент кода, записанный внутри этой функции, становится частью критического раздела, который одновременно может выполнять только один поток.
Это только обеспечивает безопасность резьбы; это не гарантирует этого. Я имею в виду, что вы нанимаете опытного водителя для своей машины, но это не гарантирует, что машина не попадет в аварию. Однако вероятность остается малейшей.
Атомный - его нельзя сломать, поэтому результат ожидается. С неатомным - когда другой поток получает доступ к зоне памяти, он может изменить его, поэтому результат является неожиданным.
Code Talk:
Атомная марка getter и setter свойства нити безопасна. например, если вы написали:
self.myProperty = value;
это нить безопасна.
[myArray addObject:@"Abc"]
НЕ является безопасным.
Нет такого ключевого слова "атомный"
@property(atomic, retain) UITextField *userName;
Мы можем использовать вышеупомянутое как
@property(retain) UITextField *userName;
См. Вопрос переполнения стека https://stackoverflow.com/questions/8036604.
default является «атомным», это означает, что он стоит вашей производительности всякий раз, когда вы используете свойство, но это безопасно для потоков. То, что делает 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
С другой стороны, «неатомный» ничего не добавляет к вашему коду. Так что это безопасно только в том случае, если вы сами кодируете механизм безопасности.
@property(nonatomic, retain) UITextField *userName;
Не забывайте, это не значит, что свойство в целом является защищенным от потоков. Только метод вызова установщика / установщика. Но если вы используете сеттер и после этого одновременно получаете 2 разных потока, он также может быть сломан!
атомный (по умолчанию)
Атомный - это значение по умолчанию: если вы ничего не вводите, ваша собственность есть атомный. Атомное свойство гарантировано, если вы попытаетесь прочитать это, вы получите действительное значение. Это не дает никаких гарантий о том, что это за значение, но вы получите хорошие данные, нет просто ненужная память. Это позволяет вам сделать, если у вас есть несколько потоки или несколько процессов, указывающих на одну переменную, одну нить может читать, а другая тема может писать. Если они бьют в то же самое время, поток считывателя гарантированно получит одно из двух значений: либо до изменения, либо после изменения. Что атомного не делает дать вам любую гарантию того, какие из этих ценностей вы может получить. Атомный действительно обычно путают с безопасностью потоков и это не правильно. Вы должны гарантировать безопасность вашей нити другие способы. Тем не менее, атомная энергия гарантирует это, если вы попытаетесь читать Вы получаете какую-то ценность.
неатомный
С другой стороны, не атомический, как вы можете догадаться, просто означает, «Не делай этого атомного материала.«То, что вы теряете, это то, что гарантирует вам всегда что-то возвращай. Если вы попытаетесь прочитать в середине а напишите, вы можете вернуть данные мусора. Но, с другой стороны, вы идете немного быстрее. Потому что атомные свойства должны творить магию чтобы гарантировать, что вы вернете ценность, они немного медленнее. Если это свойство, к которому вы обращаетесь много, вы можете отказаться вплоть до неатомных, чтобы убедиться, что вы не несете эту скорость штраф.
Смотрите больше здесь: https://realm.io/news/tmi-objective-c-property-attributes/
Если вы используете свое свойство в многопоточном коде, вы сможете увидеть разницу между неатомными и атомными атрибутами. Нонатомический быстрее атомного, а атомный - безопасный, а не атомный.
Виджаендра Трипати уже привел пример для многопоточной среды.
Прежде чем начать: вы должны знать, что каждый объект в памяти должен быть выделен из памяти, чтобы появился новый писатель. Вы не можете просто написать поверх чего-то, как вы делаете на бумаге. Вы должны сначала стереть (деаллок) его, а затем вы можете написать на него. Если в момент, когда удаление выполнено (или наполовину сделано) и ничего еще не было написано (или наполовину написано), и вы попытаетесь прочитать это, это может быть очень проблематично! Атомная и неатомная помощь поможет вам решить эту проблему по-разному.
Сначала прочитайте это вопрос, а затем прочитайте Ответ Bbum. Кроме того, тогда прочитайте мое резюме.
«атомный» ВСЕГДА гарантирует
Сохранить подсчеты - это способ управления памятью в Objective-C . Когда вы создаете объект, он имеет количество удерживаемых 1. Когда вы отправляете объект удерживает сообщение, его удержание увеличивается на 1. Когда Вы отправляете объекту сообщение о выпуске, его количество сохранения уменьшается на 1. Когда вы отправляете объекту сообщение об авторелизе , его удержание считается уменьшается на 1 на каком-то этапе в будущем. Если объект сохраняется количество уменьшается до 0, оно распределяется.
Какая?! Различаются многопоточность и безопасность потока?
Да. Многопоточность означает: несколько потоков могут читать общий фрагмент данных одновременно, и мы не потерпим крах, но это не гарантирует, что вы не читаете с неавтореализованной стоимости. С безопасностью потоков гарантируется, что то, что вы читаете, не будет автоматически выпущено. Причина, по которой мы не делаем все атомным по умолчанию, заключается в том, что существует стоимость производительности, и для большинства вещей на самом деле не требуется безопасность потоков. Несколько частей нашего кода нуждаются в этом, и для этих нескольких частей нам нужно написать наш код в режиме защиты от потоков, используя блокировки, мьютекс или синхронизацию.
nonatomic
В целом они отличаются в 2 аспектах:
Сокрушение или нет из-за наличия или отсутствия пула авторелизы.
Позволяет читать прямо в середине «еще не законченного значения записи или пустого значения» или не позволяет и позволяет читать только тогда, когда значение написано полностью .
Как заявить:
Как атомный по умолчанию так,
@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 не атомарно **, то
* Теперь, если свойство name является атомным **
Вот почему атомная энергия называется потоком Safe и Вот почему это называется сейфом для чтения и записи
Такая операция ситуации будет выполняться последовательно. И медленный в производительности
- Неатомный означает, что переменная имеет доступ к нескольким потокам (динамический тип).
- Неатомный поток небезопасен.
- но это быстро в производительности
- Ненатомическое поведение НЕ является поведением по умолчанию, нам нужно добавить неатомное ключевое слово в атрибут свойства.
Для в Свифте Подтверждение того, что свойства Swift являются неатомными в смысле ObjC. Одна из причин заключается в том, что вы думаете о том, достаточна ли атомность для каждого объекта для ваших нужд.
Ссылка: https://forums.developer.apple.com/thread/25642
Для получения дополнительной информации, пожалуйста, посетите сайт Http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html
Атомное свойство обеспечивает сохранение полностью инициализированного значения независимо от того, сколько потоков выполняет getter & сеттер на нем.
Неатомное свойство указывает, что синтезированные ресекторы просто устанавливают или возвращают значение напрямую, без каких-либо гарантий относительно того, что произойдет, если к одному и тому же значению будет обращаться одновременно из разных потоков.
Атомный означает, что только один поток может получить доступ к переменной одновременно (статический тип). Атомный безопасен для потоков, но медленный.
Ненатомический означает, что несколько потоков могут получить доступ к переменной одновременно (динамический тип). Нонатомический неэфирный, но быстрый.