- 모든 비용을 피하기 =)
NSObjects 확실히 기본적으로 하지 스레드입니다. 원자 속성을 사용한다고해서 클래스가 threadsafe가되지는 않습니다 (이는 오해의 여지가 있기 때문에 추가되었습니다).
일반적인 해결책은 모든 변경 가능한 상태가 적절한 잠금 (예 : 뮤텍스 또는 @synchronized
)으로 보호되는지 확인하는 것입니다.
내가 가변적 인 상태라고 말할 때, 나는 외부 적으로 또는 내부적으로 변이 할 수있는 대상을 언급하고있다. 잘 모르는 경우 여러 스레드에서 유형을 읽거나 쓰려면 잠금을 설정하십시오. 이것은 항상 읽고 쓰는 일에서 일어나야합니다. 읽기가 많은 경우에는 읽기 쓰기 잠금이 더 우수하고 특수한 잠금이 될 수 있습니다.
더 자세히 대답하려면 몇 가지 코드를 게시해야합니다. 그것은 datacontroller의 재산 내부의 객체가 안전하게 스레드인지 여부를 결정하는 것이이 시나리오에서
업데이트
인가 ..? 내 datacontroller 마찬가지로 NSMutableArray 및 스레드가 안전하지 않습니다 nonatomic 설정됩니다. 이 경우 그 가치는 어떻게 될 것입니까?
전이적인 것으로 생각하십시오. 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
경계에서 잠금 및 잠금 해제하는 것과 같습니다.
@interface MONCookie : NSObject <NSCopying>
{
@private
NSRecursiveLock * lock;
}
@end
@implementation MONCookie
- (id)init
{
self = [super init];
if (nil != self) {
lock = [NSRecursiveLock new];
}
return self;
}
- (void)temperatureDidIncrease
{
// ...
}
- (void)bake
{
// use the same lock for everything
// do not mix @synchronized in some places, and use of the lock
// in others. what you use to protect the data must remain consistent
//
// These are equivalent approaches to protecting your data:
{ // @synchronized:
@synchronized(self) {
[self temperatureDidIncrease];
}
}
{ // using the lock:
[lock lock];
[self temperatureDidIncrease];
[lock unlock];
}
}
@end
내가 어떤 코드가없는이 .. 난 그냥 여기에 이론 부분으로 갈거야 ... 당신이 데이터 컨트롤러 스레드를 만드는 방법을 보여 일부 샘플 코드에 나를 인도 할 수 안전 ... –
시스템은 pthreads를 제공합니다 - 많은 예제가 존재합니다. NSLock 사용을 위해 iOS 및 OS X 샘플을 참조 할 수도 있습니다. pthread 샘플은 샘플 코드보다 잠금 및 스레드 안전성을 실제로 설명하기 때문에 더 좋습니다. – justin
한 가지 더 .. "NSObjects는 기본적으로 threadsafe가 아닙니다. 원자 속성을 사용하면 클래스가 threadsafe가되지 않습니다. 그렇다면 비 원자학적인 것은 무엇입니까? 또는 기본적으로 원자가? –