2012-01-06 3 views
3

객관적인 방법으로 스레드 안전 싱글 톤 객체를 만드는 방법은 무엇입니까? 예를 들면. 싱글 톤 객체 인 공유 데이터 컨트롤러가 있다면 둘 이상의 스레드가 동시에 액세스하는 경우 어떻게됩니까? 또는 이러한 객체는 기본적으로 스레드 안전성을 갖습니다.스레드 안전 싱글 톤 객체가 objective-c에 있습니까?

갱신 :

는 datacontroller의 재산 내부의 객체가 스레드 안전인지 아닌지를 결정하는 것이이 시나리오 아래인가 ..? 내 datacontroller 마찬가지로 NSMutableArray 및 스레드가 안전하지 않습니다 nonatomic 설정됩니다. 이 경우 그 가치는 어떻게 될 것입니까?

갱신 : 2

그리고 @synchronized(self)이 실제로 무엇을 하는가 ..? 데이터 컨트롤러가없는 스레드의 경우, 정의되지 않은 동작이 일어날 수

답변

5

- 모든 비용을 피하기 =)

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 
+0

내가 어떤 코드가없는이 .. 난 그냥 여기에 이론 부분으로 갈거야 ... 당신이 데이터 컨트롤러 스레드를 만드는 방법을 보여 일부 샘플 코드에 나를 인도 할 수 안전 ... –

+0

시스템은 pthreads를 제공합니다 - 많은 예제가 존재합니다. NSLock 사용을 위해 iOS 및 OS X 샘플을 참조 할 수도 있습니다. pthread 샘플은 샘플 코드보다 잠금 및 스레드 안전성을 실제로 설명하기 때문에 더 좋습니다. – justin

+0

한 가지 더 .. "NSObjects는 기본적으로 threadsafe가 아닙니다. 원자 속성을 사용하면 클래스가 threadsafe가되지 않습니다. 그렇다면 비 원자학적인 것은 무엇입니까? 또는 기본적으로 원자가? –

-5

내가 전에 목표 C에서 프로그래밍하지 않은하지만 부울 을 isLocked처럼 지금까지의 내가 운영 체제 코스에서 아는 한, 당신이 당신의 싱글 톤 객체에 공유 부울 변수를 넣어야 때마다 스레드를 해당 클래스에 액세스하려고하면 다음을 수행해야합니다. 나는 이것을 엄격한 교대라고 부른다 : good old school days.

스레드 A :

if(!isLocked) { 
isLocked = True; 
Do the stuff 
isLocked = False; 
} 
+1

이것은 완료되지 않은 방법입니다. 검사 된 잠금 장치는 쓸모가 없습니다. 잠금, 작동, 잠금 해제. – justin