2011-08-12 6 views
2

사용자가 init을 호출하지 않도록하려면 어떻게해야합니까? 대신 클라이언트가 sharedSingleton을 호출하여 공유 인스턴스를 가져와야합니다.objc의 싱글 톤 패턴, init을 비공개로 유지하는 방법?

@synthesize delegate; 

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     // Initialization code here. 
    } 

    return self; 
} 

+ (LoginController *)sharedSingleton 
{ 
    static LoginController *sharedSingleton; 

    @synchronized(self) 
    { 
     if (!sharedSingleton) 
      sharedSingleton = [[LoginController alloc] init]; 
     CdtMiscRegisterConnectionChangeListenerObjc(test_ConnectionChangeListenerCallback); 
     return sharedSingleton; 
    } 
} 

답변

0

Objective-C에서 메소드를 비공개로 설정할 수 없습니다. 잘못된 이니셜 라이저가 호출되면 NSException을 발생시킬 수 있습니다.

- (id)init 
{ 
    [NSException exceptionWithName:@"InvalidOperation" reason:@"Cannot invoke init." userInfo:nil]; 
} 
2

짧은 대답 : 할 수 없습니다. Objective-C에는 개인 메소드에 대한 개념이 없습니다.

this similar question에 대한 답변을 확인하십시오.

+2

그들은, 비록 확장 (AKA "빈 카테고리")을 에뮬레이트 할 수 있습니다 구현한다. –

7

나는 그것을 두 가지 방법으로 보았다.

  1. init 안에 예외를 던집니다.
  2. init에 의해 반환 된 객체가 싱글 톤 객체가되도록하십시오.

다만이 점을 명심하십시오. 불필요하며 싱글 톤을 테스트하고 하위 클래스로 분류하기가 너무 어렵습니다.

편집 초기화에 예외를 던져

예를 추가

- (instancetype)init { 
    [self doesNotRecognizeSelector:_cmd]; 
    return nil; 
} 

- (instancetype)initPrivate { 
    self = [super init]; 
    if (self) { 
    } 
    return self; 
} 

+ (instancetype)sharedInstance { 
    static MySingleton *sharedInstance; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     sharedInstance = [[self alloc] initPrivate]; 
    }); 
    return sharedInstance; 
} 

은 초기화하여 싱글

- (instancetype)init { 
    return [[self class] sharedInstance]; 
} 

- (instancetype)initPrivate { 
    self = [super init]; 
    if (self) { 
    } 
    return self; 
} 

+ (instancetype)sharedInstance { 
    static MySingleton2 *sharedInstance; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     sharedInstance = [[self alloc] initPrivate]; 
    }); 
    return sharedInstance; 
} 
+0

그리고 두 가지 대답이 틀렸다고 생각합니다. init 메소드가 예외를 throw하면 sharedSingleton을 만들 수 없습니다. 또한 싱글 톤 객체를 반환하면 싱글 톤이 init을 다시 호출하기 때문에 무한 루프가 발생합니다. –

+0

예제를 제공하기 위해 해답을 편집 했으므로 구현 세부 사항을 자세히 살펴 보았습니다. – kubi

2

사용 UNAVAILABLE_ATTRIBUTEinit 방법을 폐지 반환하고 구현 적이 initPrivate

+ (instancetype)shareInstance; 

- (instancetype)init UNAVAILABLE_ATTRIBUTE; 
+ (instancetype)new UNAVAILABLE_ATTRIBUTE; 
나는 그것이 상속 초기화를 숨길 것이라고 생각하지만 16,

+ (instancetype)shareInstance { 
    static MyClass *shareInstance = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     shareInstance = [[super allocWithZone:NULL] initPrivate]; 
    }); 
    return shareInstance; 
} 

- (instancetype)initPrivate { 
    self = [super init]; 
    if (self) { 

    } 
    return self; 
} 

// MARK: Rewrite 
+ (id)allocWithZone:(struct _NSZone *)zone { 
    return [MyClass shareInstance]; 
} 

- (id)copyWithZone:(NSZone *)zone 
{ 
    return self; 
}