Я перехожу с кодом безопасности потока от @synchronized
до NSRecursiveLock
.Возвращаемые значения из методов с использованием NSRecursiveLock
Рассмотрим этот код, в котором myItemsArray
является NSMutableArray
:
- (NSUInteger) numberOfItems {
@synchronized(self.myItemsArray) {
return self.myItemsArray.count;
}
}
Я считаю, что следующий код неверен, потому что замок никогда не получил бы разблокирована:
- (NSUInteger) numberOfItems {
[self.myRecursiveLock lock];
return self.myItemsArray.count;
[self.myRecursiveLock unlock];
}
Поэтому я использую этот подход вместо этого:
- (NSUInteger) numberOfItems {
[self.myRecursiveLock lock];
NSUInteger itemCount = self.myItemsArray.count;
[self.myRecursiveLock unlock];
return itemCount;
}
Однако, я тонкий k этот подход нарушит безопасность потока, так как другая нить может добавить или удалить элемент после-unlock
, но доitemCount
.
Я не уверен, если я правильно, что последний подход не является поточно-безопасным, потому что я вижу эту модель во многих широко используемых сторонних библиотеках (например, [AFHTTPRequestOperation -responseObject]
)
Что такое правильный способ вернуть значение из метода, синхронизированного с использованием NSRecursiveLock
?
Защита 'numberOfItems' никогда не может гарантировать, что счетчик обновлен. Массив может быть изменен другим потоком сразу после возврата метода. Это предотвращает одновременный вызов двух потоков методом count. –
@MartinR Спасибо за этот комментарий, который помог мне переосмыслить мой подход (теперь это значительно улучшилось). Я с радостью принимаю это как ответ. –