如何确保用户不调用init,而客户端应该调用sharedSingleton来获取共享实例。
@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 :(得分:6)
我见过它有两种方式。
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;
}
答案 1 :(得分:5)
使用UNAVAILABLE_ATTRIBUTE
取消init
方法,并实施initPrivate
+ (instancetype)shareInstance;
- (instancetype)init UNAVAILABLE_ATTRIBUTE;
+ (instancetype)new UNAVAILABLE_ATTRIBUTE;
实施
+ (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;
}
答案 2 :(得分:2)
简短的回答:你做不到; Objective-C没有私有方法的概念。
查看this similar question的答案。
答案 3 :(得分:0)
您无法在Objective-C中将方法设为私有。如果调用了错误的初始化程序,您可以引发NSException。
- (id)init
{
[NSException exceptionWithName:@"InvalidOperation" reason:@"Cannot invoke init." userInfo:nil];
}