在iOS/OS X应用程序中,我应该在哪里初始化我的单例?
我想初始化我的singleton对象,它在我的应用程序中存储和管理整个类的应用程序设置。此外,应在启动时通过从在iOS/OS X应用程序中,我应该在哪里初始化我的单例?,ios,cocoa,singleton,uiapplicationdelegate,Ios,Cocoa,Singleton,Uiapplicationdelegate,我想初始化我的singleton对象,它在我的应用程序中存储和管理整个类的应用程序设置。此外,应在启动时通过从NSUserDefaults加载数据来初始化singleton实例。但是,我不完全确定在启动时应该在哪里初始化singleton 在Cocoa应用程序中,我首先在applicationWillFinishLaunching:中编写了单例初始化代码,从NSUserDefaults中获取参数。但是,后来我发现,如果我在脚本中设置的初始视图控制器中编写单例初始化代码(不带参数!),这将无法正常
NSUserDefaults
加载数据来初始化singleton实例。但是,我不完全确定在启动时应该在哪里初始化singleton
在Cocoa应用程序中,我首先在applicationWillFinishLaunching:
中编写了单例初始化代码,从NSUserDefaults
中获取参数。但是,后来我发现,如果我在脚本中设置的初始视图控制器中编写单例初始化代码(不带参数!),这将无法正常工作,因为视图将加载:
,viewdiload:
在应用程序将完成启动之前调用视图控制器类的等:
所以现在我确定我应该在viewWillLoad:
中编写singleton初始化代码,而不是在应用程序willfinishLaunching
之前,但仍然不确定它是否合适。具体来说,我知道NSApplicationMain
是启动时调用的第一个方法,但下一个方法似乎不是AppDelegate
中的任何东西,至少如果您使用故事板
总而言之,我想问以下问题:
- 如果使用情节提要,则在
NSApplicationMain
之后将从哪个类调用哪个方法
- 在我的应用程序中,我应该在哪里编写我的单例初始化代码?我想尽快初始化它
- iOS和OS X应用程序之间有什么不同吗
懒惰总是赢
如果你能做到这一点:尽可能晚:)并且总是做最少的事情(但是尽可能多地保持代码干净!)你应该在第一次访问它时初始化它。也许是这样的:
+ (instancetype)sharedInstance {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init];
});
return _instance;
}
作为一个旁注,如果您只使用这个类作为对NSuSerdRebug < /C> >的访问器,您可能需要考虑使用静态方法来代替。
+ (id)mySpecificDataPoint {
return [[NSUserDefaults standardUserDefaults] objectForKey:@"whatever"];
}
+ (void)setMySpecificDataPoint:(id)data {
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"whatever"];
}
或者,出于此目的,一种设计更为完善的方法可能是将一个类别添加到NSUserDefaults
@interface NSUserDefaults (MyData)
@property (nonatomic) NSString *someDataPoint;
@property (nonatomic) NSInteger somePrimitiveDataPoint;
@end
@implementation NSUserDefaults (MyData)
- (NSString *)someDataPoint {
return [self objectForKey:@"someDataPoint"];
}
- (void)setSomeDataPoint:(NSString *)someDataPoint {
[self setObject:someDataPoint forKey:@"someDataPoint"];
}
- (NSInteger)somePrimitiveDataPoint {
return [[self objectForKey:@"somePrimitiveDataPoint"] integerValue];
}
- (void)setSomePrimitiveDataPoint:(NSInteger)somePrimitiveDataPoint {
[self setObject:@(somePrimitiveDataPoint) forKey:@"somePrimitiveDataPoint"];
}
@end
当您必须使用它时,您可以初始化单例。正如Daji Djan所说:懒惰才是赢家。请注意,您不应该在应用程序willfinishLaunching
中执行长时间运行的过程,它应该尽快返回
如果在applicationWillFinishLaunching期间单例不是必需的,那么如果您需要尽快初始化它,您应该在第一个视图控制器的ViewWillExeal中调用它。您可以在initialize
中调用它,如果您需要它,那么单例的美妙之处在于,至少从单例的角度来看,首先在哪里引用singleton并不重要。singleton的sharedInstance
代码(或您所称的任何代码)应进行所有必要的配置,并且无论在代码中首次遇到sharedInstance
方法的何处,都将进行此初始配置。感谢您的回答。尽快初始化它是愚蠢的吗?我认为它花费的时间非常少,并且改进了维护……啊,我喜欢将singleton实现的一部分作为NSUserDefaults
的访问器!。我费心从user default加载值,并将其作为参数抛出到singleton的init。。。谢谢。问题已标记为swift
,但您的答案是用Objective-C编写的。也许您也可以使用swift code更新您的答案?@sbooth,已删除swift
标记。该问题应同时适用于Swift和Objective-C。