通过类方法和实例方法创建Singleton的差异

时间:2014-10-23 16:37:16

标签: objective-c

使用以下方法创建单例类的含义是什么:

+ (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;
}

我已经看到它们都被使用过,并希望了解它们如何影响性能,简单代码,调试等。

2 个答案:

答案 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委托实例上。

这不会产生任何值得讨论的性能差异。最大的区别在于, 第一个代码段可让您访问单例而不会对应用委托创建额外的依赖 ,这是一件好事:这可以避免“污染”您的应用委托代码与应用程序状态不直接相关。