Singleton for a UIViewController with a xib



由于我的应用程序有多个LoginViewController没有意义,我尝试将单例模式与 initWithNibName 相结合,如下所示:

+ (instancetype)sharedInstance {
    static id sharedInstance;
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        sharedInstance = [super initWithNibName:@"LoginViewController" bundle:nil];
    });
    return sharedInstance;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    NSLog(@"ignoring initWithNibName and calling sharedInstance");
//    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
//    if (self) {
//
//    }
    return [LoginViewController sharedInstance];
}

问题是该行:

sharedInstance = [super initWithNibName:@"LoginViewController" bundle:nil];

给我这个错误:

No known class method for selector 'initWithNibName:bundle:'

那么,如果通常在initWithNibName:bundle中调用完全相同的代码,情况如何呢?我怀疑这是因为共享实例是一个静态方法,而 UIViewController 没有用于initWithNibName:bundle的静态方法。

不过,我想知道是否有办法解决它,因为我不想每次需要使用它时都创建 LoginViewController。

我还想防止调用LoginViewController initWithNibName:bundle:并获得单独的实例。

+sharedInstance是一个

类方法,因此self内部计算类LoginViewControllersuper引用类UIViewController。 -initWithNibNamed:bundle:是一个实例方法。

static LoginViewController *sharedInstance;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    if(sharedInstance) {
        // avoid creating more than one instance
        [NSException raise:@"bug" format:@"tried to create more than one instance"];
    }
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if(self) {
        // own initialization code here
    }
    return self;
}
+ (LoginViewController *)sharedInstance
{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        sharedInstance = [[LoginViewController alloc] initWithNibName:@"LoginViewController" bundle:nil];
    });
    return sharedInstance;
}

-init 方法族有一个隐式契约,表示 alloc+init 应始终返回一个新对象或语义上与新对象无法区分的对象。 例如 [NSNumber numberWithInt:2] 不一定总是返回一个新对象,因为不需要区分两个不同的 2。

因此,您有两种选择:1( 如果有人尝试创建其他LoginViewController,则引发异常,或 2( 允许创建其他LoginViewController。第三个选项 ( 3( 如果有人尝试创建新的 LoginViewController ,则返回共享实例(破坏了初始化的约定,这意味着它将向调用者返回一些他没有预料到的东西!如果调用方知道 LoginViewController 是单例,则应使用 +sharedInstance 。如果调用方不知道这一点,他应该得到一个异常或一个新的 LoginViewController。

最新更新