В Objective C Я использую экземпляр NSMutableArray из разных потоков, и я использую @synchronized, чтобы сделать его потокобезопасным. в настоящее время все мои обращения к этому массиву защищены блоком @synchronized, даже методом objectAtIndex :. Тем не менее, мне интересно, какие методы действительно требуют защиты с помощью @synchronized. мне нужно защитить доступ для чтения?Коллекция NSMutableArray и @ Синхронизированные блоки
Что произойдет, если «ObjectAtIndex» не будет защищен и вызван одновременно с «removeObject»?
Если все методы защищены с помощью @synchronized, что относительно производительности? (Я создаю игровой сервер tcp/udp и на самом деле не хочу перестраивать этот массив, если он уменьшит перфект или создаст блокировки).
Например, я полагаю, что метод 'containsObject:' будет перечислять для поиска объекта и что я должен избегать совпадающего вызова 'removeObject:' в другом потоке.
Возможно, хорошим решением будет иметь слишком разные замки (для чтения и записи) ...
Помощь и предложения приветствуются!
Большое спасибо.
Пожалуйста найти пример кода ниже для иллюстрации:
@interface TestClass : NSObject
{
NSMutableArray * array;
}
@end
@implementation TestClass
- (id)init
{
self = [super init];
if (self)
{
array = [NSMutableArray array];
}
return self;
}
-(id)objectAtIndex:(NSUInteger)index
{
@synchronized(array) **// IS IT USEFUL OR NOT ??**
{
return [array objectAtIndex:index];
}
}
-(void)removeObject:(id)object
{
@synchronized(array)
{
[array removeObject:object];
}
}
-(void)compute
{
@synchronized(array)
{
for (id object in array)
{
[object compute];
}
}
}
@end
Мне очень нравится решение GCD. Поскольку я использую многие изменчивые массивы (и словарь тоже), которые я бы хотел защитить, я задаюсь вопросом, могу ли я создать свой собственный GCDMutableArray и GCDMutableDictionary, которые переопределили бы все методы и добавили dispatch_queue_t для каждого экземпляра массива или словаря. Но является ли это хорошим решением, чтобы иметь 10 изменяемых словарей со своим собственным dispatch_queue? А для создания отдельной очереди в каждом экземпляре? dispatch_queue_create принимает имя как arg, как сгенерировать это имя? Возможно, этот вид защищенного массива и dict уже был написан ... но ничего не может найти. –
Я не думаю, что такие классы, как правило, полезны. Практически никогда не бывает проблем с безопасностью потоков, концентрируясь на низкоуровневых классах, таких как контейнеры. Вы почти наверняка должны анализировать свои классы на уровне своей абстракции, чтобы * конструировать * свои интерфейсы, а не только их реализации, для обеспечения безопасности потоков. Тем не менее, очереди отправки дешевы, и Apple поощряет вас создавать столько, сколько требует разумный дизайн. –