我应该在 iOS/OS X 应用程序中的什么地方初始化我的单身人士?

Where should I initialize my singleton in iOS/OS X app?

我想初始化我的单例对象,它在我的应用程序中存储和管理整个 class 的应用程序设置。此外,应该通过在启动时从 NSUserDefaults 加载数据来初始化单例实例。但是,我不确定在启动时应该在哪里初始化单例。

在Cocoa app中,我首先在applicationWillFinishLaunching:中编写了单例初始化代码,从NSUserDefaults中获取参数。但是,后来我发现,如果我还在我的初始视图控制器中编写单例初始化代码(不带参数!),这将无法正常工作,在情节提要中设置,因为 viewWillLoad:viewDidLoad: 等.view controller的class在applicationWillFinishLaunching:.

之前被称为before

所以现在我确定我应该在viewWillLoad:内写单例初始化代码早于applicationWillFinishLaunching,但仍然不确定是否合适.具体来说,我知道 NSApplicationMain 是启动时调用的第一个方法,但似乎下一个方法不在 AppDelegate 内,至少如果您使用故事板。

总结一下,我想问的是:

懒惰永远赢

如果你能侥幸逃脱:越晚越好:)并且总是做最少的事情(但尽可能多地保持你的代码干净!)

您应该在首次访问时对其进行初始化。可能是这样的:

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

附带说明一下,如果您实际上只是将此 class 用作 NSUserDefaults 的访问器,您可能需要考虑改用静态方法。

+ (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 所说:懒惰获胜。请注意,你不应该在你的 applicationWillFinishLaunching 中做一个长 运行 的过程,它应该尽快 return。

如果单例在applicationWillFinishLaunching时不是必须的,如果你需要尽快初始化它,你应该在第一个视图控制器的viewWillAppear中调用它。