2014-04-18 2 views
0

Objective-C에서 몇 가지 연습을하고 있는데 연습 중 하나는 BNRItemStore이라는 개체의 인스턴스를 만드는 것입니다. 사용되는 방법은 sharedStore가 처음 호출 될 때만이 BNRItemStore의 인스턴스가 생성되고 sharedStore가 가리 키도록 설정하는 것이라고 설명에서 다음정적 변수를 덮어 쓰지 않으십니까?

+ (instancetype)sharedStore 
{ 
    static BNRItemStore *sharedStore = nil; 
    if(!sharedStore) 
    { 
      sharedStore = [[self alloc] initPrivate]; 
    } 

    return sharedStore 
} 

입니다. 후속 호출은 이미 생성 된 호출 만 반환합니다. 그들은 또한 Obj-C에서 정적 변수가 메소드 실행이 끝나면 파기되지 않는다고 설명합니다. 당신이 만든 처음과 BNRItemStore의 새로운 인스턴스 sharedStore를 호출 한 후 다시 같은 방법으로 호출 늘 또 다른 새로운 인스턴스를 생성하고 설정 sharedStore 포인터가 새 인스턴스를 가리 키도록 경우에도 그와

는 말했다되고 ? 정적 변수를 사용하는 경우에도 메서드의 첫 번째 줄은 static 포인터를 nil로 설정하여 현재 (존재하는 경우) 포인터를 효과적으로 지울 수 있기 때문에 논리적으로 보입니다. 맞습니까?

편집 :

@implementation BNRItemStore 

+ (instancetype)sharedStore 
{ 
    static BNRItemStore *sharedStore = nil; 
    // Do I need to create a sharedStore? 
    if (!sharedStore) 
    { 
     sharedStore = [[self alloc] initPrivate]; 
    } 

    return sharedStore; 
} 

// If a programmer calls [[BNRItemStore alloc] init], let him 
// know the error of his ways 
- (instancetype)init 
{ 
    @throw [NSException exceptionWithName:@"Singleton" 
            reason:@"Use +[BNRItemStore sharedStore]" 
           userInfo:nil]; 
    return nil; 
} 

// Here is the real (secret) private initializer 
- (instancetype)initPrivate 
{ 
    self = [super init]; 
    if(self) 
    { 
     _privateItems = [[NSMutableArray alloc] init]; 
    } 
    return self; 
} 
+0

init을 사용할 때 아무런 문제가 없습니다. initPrivate를 제거하고 init 만 사용하십시오. 그것은 "사용자"가 호출 할 때 잘 작동합니다. self 대신 _sharedStore를 반환하십시오. 특히 ARC를 사용할 때 이것은 훌륭하게 작동합니다. 그러나 그것은 당신의 질문에 driectly 관련이 없습니다. 이 질문을 확인 –

+0

: http://stackoverflow.com/questions/18724522/trouble-understanding-static-class-in-ios – ayushn21

답변

0

!sharedStoresharedStore == nil입니다 작성하는 또 다른 방법 : 혼란을 정리하는 데 도움하려면, 여기에 현재 구현 파일의 전체 코드입니다. 이것은 사물을 분명히하는 데 도움이 될 수 있습니다.

처음으로 sharedStorenil으로 초기화됩니다.

처음으로 sharedStore == nil이 참이므로 sharedStore에 값이 할당됩니다 (이 값은 nil이 아님).

다음에 sharedStore이 초기화되지 않으면 이전 호출의 값이 유지됩니다.

다음에 sharedStore == nil이 거짓이므로 sharedStore에 값이 지정되지 않습니다. 여기


혼란이 초기화이며,이 할당되지 않습니다 라인 static BNRItemStore *sharedStore = nil;

이상이다. 그들은 비슷하게 생겼지 만 그것들은 같지 않습니다.

type x = value; // This initializes a new variable with value. 
x = differentValue; // This assigns an existing variable with a different value. 

정적 변수는 한 번만 초기화됩니다. 메서드가 몇 번 호출 되더라도 처음으로 초기화됩니다.

다음 호출에서 해당 코드 줄을 건너 뛰는 것으로 생각할 수 있습니다.

참고 : 이것은 Objective-C 만이 아니라 C 및 C++에서도 마찬가지입니다.

+0

의 Obj-C에서 그래서, 당신은 전무에 대한 정적 varibale을 초기화 할 때, 그리고 다음 실제 객체를 가리 키도록 수정하십시오. 다음 번에이 객체를 무시하려고 설정하면 코드가 건너 뛰고 nil로 설정되지 않습니다. 이 메소드의 첫 번째 행에서 sharedStore를 항상 nil로 설정하면 이후의 if 문은 항상 위의 행에서 nil로 설정 되었기 때문에 항상 실행됩니다. 이것은 틀린가? – RomeTizzle

0
@implementation BNRItemStore 

static BNRItemStore *sharedStore = nil; 

+ (instancetype)sharedStore 
{ 

    // Do I need to create a sharedStore? 
    if (!sharedStore) 
    { 
     sharedStore = [[self alloc] init]; 
    } 

    return sharedStore; 
} 

// Here is the real (secret) private initializer 
- (instancetype)init 
{ 
    // if you really want to raise an exception here, then simply compare 
    // self == sharedStore. When they are not equal then raise the exception here. 
    if (!sharedStore) { 

     sharedStore = [super init]; 
    } 
    return sharedStore;; 
} 
0

sharedStore 메서드는 스레드 세이프가 아닙니다. 쓰레드 안전성을 높이려면 @synchronized 또는 더 나은 디스패치를 ​​사용해야합니다.

@implementation BNRItemStore 

static BNRItemStore *sharedStore = nil; 

+ (instancetype)sharedStore 
{ 
    // Creates a sharedStore using dispatch once 
     static dispatch_once_t onceToken; 
     dispatch_once(&onceToken, ^{ 
      sharedStore = [[self alloc] initPrivate]; 
     }); 
    return sharedStore; 
} 

// Here is the real (secret) private initializer 
- (instancetype)initPrivate 
{ 
    self = [super init]; 
    if(self) 
    { 
     _privateItems = [[NSMutableArray alloc] init]; 
    } 
    return self; 
} 

대신 프로그래머는 단지 컴파일러가 그를 위해 오류를 만들 수 있도록, 클래스에 초기화 방법을 사용하고자하는 예외를 던지는

/그녀는 프로그래머는 그/그녀가 다루고 있음을 알 수 있도록 하나씩 일어나는 것.(런타임에 충돌보다 좋음).

싱글 톤의 .h 파일에 다음 내용을 추가하십시오.

+(instancetype) alloc __attribute__((unavailable("alloc not available, call sharedInstance instead"))); 
-(instancetype) init __attribute__((unavailable("init not available, call sharedInstance instead"))); 
+(instancetype) new __attribute__((unavailable("new not available, call sharedInstance instead"))); 

업데이트 : [self alloc]를 호출

완벽하게 유효하고, 그것은 어떤 문제를 제공하지 않습니다. 나는이 부분에 대한 @ mah의 대답에 동의하지 않는다. 배려심과 독신에 대한 더 많은 것을 여기에서 읽으십시오.

https://www.mikeash.com/pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html

관련 문제