Свойства Objective-C по умолчанию равны атомарным
, который гарантирует, что аксессоры являются атомарными, но не обеспечивает общую безопасность потоков (согласно этот вопрос ). Мой вопрос: не являются ли атомарные свойства избыточными в большинстве сценариев параллелизма? Например:
Сценарий 1: изменяемые свойства
@interface ScaryMutableObject : NSObject {}
@property (atomic, readwrite) NSMutableArray *stuff;
@end
void doStuffWith(ScaryMutableObject *obj) {
[_someLock lock];
[obj.stuff addObject:something]; //the atomic getter is completely redundant and could hurt performance
[_someLock unlock];
}
//or, alternatively
void doStuffWith(ScaryMutableObject *obj) {
NSMutableArray *cachedStuff = obj.stuff; //the atomic getter isn't redundant
[_someLock lock];
[cachedStuff addObject:something]; //but is this any more performant than using a nonatomic accessor within the lock?
[_someLock unlock];
}
Сценарий 2: неизменяемые свойства
Я думал, что, возможно, атомарные свойства будут полезны для избежания блокировок при работе с неизменяемыми объектами, но поскольку неизменяемые объекты могут указывать на изменяемые объекты в Objective-C это не особо помогает:
@interface SlightlySaferObject : NSObject {}
@property (atomic, readwrite) NSArray *stuff;
@end
void doStuffWith(SlightlySaferObject *obj) {
[[obj.stuff objectAtIndex:0] mutateLikeCrazy];//not at all thread-safe without a lock
}
Единственные сценарии, которые я могу придумать, когда безопасно использовать атомарные аксессоры без блокировки (и, следовательно, вообще стоит использовать атомарные свойства):
Сценарий 1: изменяемые свойства
@interface ScaryMutableObject : NSObject {}
@property (atomic, readwrite) NSMutableArray *stuff;
@end
void doStuffWith(ScaryMutableObject *obj) {
[_someLock lock];
[obj.stuff addObject:something]; //the atomic getter is completely redundant and could hurt performance
[_someLock unlock];
}
//or, alternatively
void doStuffWith(ScaryMutableObject *obj) {
NSMutableArray *cachedStuff = obj.stuff; //the atomic getter isn't redundant
[_someLock lock];
[cachedStuff addObject:something]; //but is this any more performant than using a nonatomic accessor within the lock?
[_someLock unlock];
}
Сценарий 2: неизменяемые свойства
Я думал, что, возможно, атомарные свойства будут полезны для избежания блокировок при работе с неизменяемыми объектами, но поскольку неизменяемые объекты могут указывать на изменяемые объекты в Objective-C это не очень помогает:
@interface SlightlySaferObject : NSObject {}
@property (atomic, readwrite) NSArray *stuff;
@end
void doStuffWith(SlightlySaferObject *obj) {
[[obj.stuff objectAtIndex:0] mutateLikeCrazy];//not at all thread-safe without a lock
}
Единственные сценарии, которые я могу придумать, когда безопасно использовать атомарные аксессоры без блокировки (и, следовательно, вообще стоит использовать атомарные свойства):
Сценарий 1: изменяемые свойства
@interface ScaryMutableObject : NSObject {}
@property (atomic, readwrite) NSMutableArray *stuff;
@end
void doStuffWith(ScaryMutableObject *obj) {
[_someLock lock];
[obj.stuff addObject:something]; //the atomic getter is completely redundant and could hurt performance
[_someLock unlock];
}
//or, alternatively
void doStuffWith(ScaryMutableObject *obj) {
NSMutableArray *cachedStuff = obj.stuff; //the atomic getter isn't redundant
[_someLock lock];
[cachedStuff addObject:something]; //but is this any more performant than using a nonatomic accessor within the lock?
[_someLock unlock];
}
Сценарий 2: неизменяемые свойства
Я думал, что, возможно, атомарные свойства будут полезны для избежания блокировок при работе с неизменяемыми объектами, но поскольку неизменяемые объекты могут указывать на изменяемые объекты в Objective-C это не очень помогает:
@interface SlightlySaferObject : NSObject {}
@property (atomic, readwrite) NSArray *stuff;
@end
void doStuffWith(SlightlySaferObject *obj) {
[[obj.stuff objectAtIndex:0] mutateLikeCrazy];//not at all thread-safe without a lock
}
Единственные сценарии, которые я могу придумать, когда безопасно использовать атомарные аксессоры без блокировки (и, следовательно, вообще стоит использовать атомарные свойства):
NSString
или NSArray
из
неизменяемые объекты) Я что-то упустил? Есть ли другие веские причины использовать атомарные свойства?