Большинство классов / функций UIKit не являются поточно-ориентированными (UIGraphics недавно была сделана несколько поточно-ориентированной, по-видимому, но я подозреваю, что UIView все еще не является), поэтому нет смысла использовать атомарные свойства. Атомарное свойство «retain» исключает только такие условия гонки (при условии, что назначения указателей уже атомарные):
- Тема A делает
NSLog([obj.property description]);
- Поток B выполняет
obj.property = nil;
, вызывая освобождение свойства. Если это произойдет в какой-то момент между A, получающим свойство и печатающим его с помощью NSLog, он может потерпеть крах (например, строка «description» может принадлежать объекту и может исчезнуть при его освобождении).
Как правило, вам нужно намного больше , чем атомарные методы получения / установки для большинства видов синхронизации потоков; установщик получает блок @synchronized, а получатель (при условии, что свойство «retain») получает блок @synchronized, retain и autorelease. Синхронизированный блок состоит из вызовов методов _lock и _unlock (IIRC). Это четыре вызова метода и обработчик исключений!
Делать свойства атомарными для «потокобезопасности» или «робастности» - это все равно, что делать переменные нестабильными «для робастности» вместо использования барьеров памяти - это может показаться более безопасным, но обычно это просто добавляет дополнительные издержки без пользы и может скрывать основные проблемы параллелизма.
РЕДАКТИРОВАТЬ: И да, авто-релиз должен быть в геттер, а не сеттер. В противном случае объект принадлежит пулу автоматического выпуска B, который может быть выпущен в любое время, но он будет скрывать ошибку, поскольку объект будет задерживаться дольше, прежде чем его освободят.