2014-02-11 2 views
0

Я перехожу с кодом безопасности потока от @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?

+1

Защита 'numberOfItems' никогда не может гарантировать, что счетчик обновлен. Массив может быть изменен другим потоком сразу после возврата метода. Это предотвращает одновременный вызов двух потоков методом count. –

+0

@MartinR Спасибо за этот комментарий, который помог мне переосмыслить мой подход (теперь это значительно улучшилось). Я с радостью принимаю это как ответ. –

ответ

1

Защита numberOfItems не может гарантировать, что счет будет актуальным. Массив может быть изменен другим потоком сразу после возврата метода. Это предотвращает одновременный вызов двух потоков методом count.

Смежные вопросы