我应该在 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
内,至少如果您使用故事板。
总结一下,我想问的是:
如果使用故事板,class 中的什么方法将在 NSApplicationMain
之后调用。
我应该在我的应用程序中的什么地方编写我的单例初始化代码?我想尽快初始化它。
iOS 和 OS X app 有区别吗?
懒惰永远赢
如果你能侥幸逃脱:越晚越好:)并且总是做最少的事情(但尽可能多地保持你的代码干净!)
您应该在首次访问时对其进行初始化。可能是这样的:
+ (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中调用它。
我想初始化我的单例对象,它在我的应用程序中存储和管理整个 class 的应用程序设置。此外,应该通过在启动时从 NSUserDefaults
加载数据来初始化单例实例。但是,我不确定在启动时应该在哪里初始化单例。
在Cocoa app中,我首先在applicationWillFinishLaunching:
中编写了单例初始化代码,从NSUserDefaults
中获取参数。但是,后来我发现,如果我还在我的初始视图控制器中编写单例初始化代码(不带参数!),这将无法正常工作,在情节提要中设置,因为 viewWillLoad:
、viewDidLoad:
等.view controller的class在applicationWillFinishLaunching:
.
所以现在我确定我应该在viewWillLoad:
内写单例初始化代码早于applicationWillFinishLaunching
,但仍然不确定是否合适.具体来说,我知道 NSApplicationMain
是启动时调用的第一个方法,但似乎下一个方法不在 AppDelegate
内,至少如果您使用故事板。
总结一下,我想问的是:
如果使用故事板,class 中的什么方法将在
NSApplicationMain
之后调用。我应该在我的应用程序中的什么地方编写我的单例初始化代码?我想尽快初始化它。
iOS 和 OS X app 有区别吗?
懒惰永远赢
如果你能侥幸逃脱:越晚越好:)并且总是做最少的事情(但尽可能多地保持你的代码干净!)
您应该在首次访问时对其进行初始化。可能是这样的:
+ (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中调用它。