使用以下方法创建单例类的含义是什么:
+ (id)sharedCoordinator {
static MyCoordinator *sharedCoordinator = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedCoordinator = [[self alloc] init];
});
}
或作为带有类方法的Application Delegate中的实例方法:
- (CoreDataHelper *)cdh {
if (!_coreDataHelper) {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
_coreDataHelper = [CoreDataHelper new];
});
[_coreDataHelper setupCoreData];
}
return _coreDataHelper;
}
我已经看到它们都被使用过,并希望了解它们如何影响性能,简单代码,调试等。
答案 0 :(得分:0)
第一个允许Singleton
类在其他地方重复使用。
第二个使单个实例对应用程序委托是私有的。
通常第一个选项更好(恕我直言。)它允许您在代码中的任何位置以结构化方式重用单个实例。
第二个选项可以保证成为单个实例,可以在一个地方私下访问。这在某些情况下可能很有用,但实际上并不是Singleton
。您可以在AppDelegate上将其设为公共属性,但为什么不使用Singleton
类?
至于性能方面的考虑,它们应该是可以忽略的。我唯一能想到的是运行时因代码中有一个额外的class
对象而导致的额外开销。
答案 1 :(得分:0)
主要区别在于第二个代码段有错误:当从多个线程同时访问cdh
时,可能会[_coreDataHelper setupCoreData]
被调用两次。
如果在cdh
为_coreDataHelper
时多个线程到达nil
,则会发生这种情况。这些线程中只有一个会继续进行[CoreDataHelper new]
调用,但所有线程都将以setupCoreData
方法结束。
进行初始化的正确方法是将设置调用放入块中,并使调用无条件:
- (CoreDataHelper *)cdh {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
_coreDataHelper = [CoreDataHelper new];
[_coreDataHelper setupCoreData];
});
return _coreDataHelper;
}
现在这两个片段几乎完全相同。唯一的区别是第一个片段使用方法静态变量来存储单例,而更新的第二个片段“搭载”在app委托实例上。
这不会产生任何值得讨论的性能差异。最大的区别在于, 第一个代码段可让您访问单例而不会对应用委托创建额外的依赖 ,这是一件好事:这可以避免“污染”您的应用委托代码与应用程序状态不直接相关。