Каким должен быть лучший способ в приложении iOS предотвратить изменение переменной экземпляра объектом, пока другой использует ее? Должно ли быть достаточно использования директивы @synchronized(self)
?
заранее спасибо
Каким должен быть лучший способ в приложении iOS предотвратить изменение переменной экземпляра объектом, пока другой использует ее? Должно ли быть достаточно использования директивы @synchronized(self)
?
заранее спасибо
Если вы хотите, чтобы объект был заблокирован, чтобы никакие два потока не использовали его одновременно, то @synchronize — это один из способов. Но это не делает его потокобезопасным.
Вы также можете использовать GCD(Grand Central Dispatch) для того же
@synchronize
(или один из множества других механизмов синхронизации) использовался именно для того, чтобы сделать его потокобезопасным. Правда, если вы сделаете это неправильно, это не сработает. И да, есть более эффективные способы создания многопоточного кода (например, Советы по безопасности потоков). Но независимо от этого, можете ли вы пояснить, что @synchronize
не делает его потокобезопасным? Я думал, что в этом вся цель методов синхронизации.
- person Rob; 13.03.2013
@synchronize
может использоваться для обеспечения безопасности потоков, хотя, как свидетельствует этот пост (и моя ссылка выше), есть лучшие способы сделать это. Это не похоже на распространенное заблуждение, что atomic
обеспечивает безопасность потоков (а это не так). @synchronize
можно, но есть и лучшие способы. Семантика, наверное.
- person Rob; 13.03.2013
Каким должен быть лучший способ в приложении iOS предотвратить изменение переменной экземпляра объектом, пока другой использует ее?
Старый добрый замок, например pthread_mutex
; вы также можете использовать оболочку Objective-C для этого (например, NSLock
и NSRecursiveLock
). @synchronized
также попадает в эту категорию, но это механизм самого высокого уровня, упомянутый здесь.
Конечно, превосходные параллельные решения обычно больше связаны с изменениями в дизайне, потоке программы, предпочтением неизменности и так далее. По-прежнему будут случаи, когда предпочтительно или требуется взаимное исключение/блокировка.
К сожалению, в этой области очень не хватает чистых ObjC/Cocoa - разработка высокоэффективной параллельной программы с использованием только технологий ObjC и Cocoa намного сложнее, чем должна быть (или должна быть).
Должно ли быть достаточно использования директивы @synchronized(self)?
Для простых случаев этого вполне достаточно. Это объектный уровень Recursive Lock.
Однако это довольно медленно по сравнению с другими вариантами взаимного исключения.
Я не думаю, что @synchronized
имеет для этого большое значение, кроме:
@synchronized
удобен, но поскольку он имеет высокую стоимость, его следует использовать с осторожностью.
Если единственная цель состоит в том, чтобы иметь возможность получить доступ
self.myString; //getter
а также,
self.myString=aString; //setter
Лучше всего объявить его атомарным, например:
@property (atomic, strong) NSString* myString;
Это гарантирует, что в многопоточной среде установка и получение myString потоком 1 защищены от действий потока 2.