Если контроллер данных не является потокобезопасным, то может произойти неопределенное поведение - избегайте его любой ценой =)
Объекты NSO определенно не по умолчанию безопасны для потоков.Использование атомарных свойств не делает класс поточным*).
Когда я говорю «изменяемое состояние», я имею в виду объект, который может мутировать внешне или внутренне.Если вы не уверены, заблокируйте, чтобы типы читались или записывались из нескольких потоков.Это должно происходить при чтении и письме - всегда.Если у вас много чтения, блокировка чтения-записи может быть лучше, более специализированной блокировкой.
Чтобы ответить более подробно, вам придется опубликовать некоторый код.
Обновление
В этом сценарии объекты внутри свойства контроллера данных решают, является ли он потокобезопасным или нет ..?Как у моего контроллера данных есть NSMutableArray, и он установлен неатомно, это не будет потокобезопасным.Что будет с его значением в этом случае?
Думайте о нем как о переходном.Ваш NSMutableArray, объекты, которые он содержит, и все внешние ссылки на них должны использоваться безопасным образом, и вы должны отслеживать все это.Как правило, вы начинаете с уменьшения того, какое изменяемое состояние вы используете.Вместо того, чтобы давать клиентам ссылку на массив, давайте им копии элементов, содержащихся в массиве.Тем временем защитите все операции чтения, записи и копирования элементов с помощью блокировки.
Для простоты я продемонстрирую использование @synchronize
:
@interface MONCookie : NSObject <NSCopying>
- (NSString *)name;
@end
@interface MONDataController : NSObject
{
@private
NSMutableArray * cookies; // << MONCookie[]
}
- (void)addCookie:(MONCookie *)cookie;
- (MONCookie *)cookieWithName:(NSString *)name;
@end
@implementation MONDataController
- (id)init
{
// no lock required here
self = [super init];
if (nil != self) {
cookies = [NSMutableArray new];
}
return self;
}
- (void)dealloc
{
// no lock required here
[cookies release], cookies = nil;
[super dealloc];
}
- (void)addCookie:(MONCookie *)cookie
{
@synchronized(self) { // now accessing cookies - lock required
[cookies addObject:cookie];
}
}
- (MONCookie *)cookieWithName:(NSString *)name
{
MONCookie * ret = nil;
@synchronized(self) { // now accessing cookies - lock required
for (MONCookie * at in cookies) {
if ([at.name isEqualToString:name]) {
ret = [at copy]; // << give them a copy if cookie is not threadsafe
}
}
}
return [ret autorelease];
}
@end
Обновление 2
@synchronized
устанавливает блокировку уровня объекта.Вы можете думать об этом как о рекурсивной (или повторно входящей) блокировке, эксклюзивной для вашего экземпляра.Это также довольно медленно по сравнению с другими подходами блокировки.Приведенный выше код использует его, он безопасен для потоков и эквивалентен удержанию рекурсивной блокировки, блокировке и разблокировке на границах @synchronized
.