Objective C - 使用共享实例创建单例

时间:2016-01-23 11:38:39

标签: ios objective-c singleton

我对在Objective-C / iOS中创建单例类有疑问。 我在哪里看到在Objective-C中创建单例类的技巧就是这段代码

+ (id)sharedManager {
    static MyManager *sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
    });
    return sharedMyManager;
}

每当我打电话给[MyManager sharedManager]时,我都会得到相同的地址。但是,我也可以写[MyManager new],在这种情况下地址不同。

1.单例类的概念是不是它将类的实例化限制为一个对象?

2.如果我们可以创建另一个对象,它不再是单身,是吗?

在我的iOS应用中,我尝试了[UIApplication new]。我在运行时遇到异常。现在,我得到了。你不能创建另一个UIApplication实例,因为它是一个单例类。

那么为什么使用共享实例被认为是创建单例类的方式或者我错了呢?

3 个答案:

答案 0 :(得分:1)

sharedManager是您用来访问单例实例的便捷方法。虽然这并不能保证该应用程序只有一个实例,但如果每个人都使用sharedManager,那么实际上只存在该经理的一个实例。

这种单身人士是方便而非实施的单身人士。您应该使用它们,原因有多种:

  • 您可以通过在单元测试中调用alloc init并使用该品牌新分配的对象来对它们进行单元测试
  • 如果您决定稍后重构经理并且不再将其用作单身,如果您从乞讨中将其视为常规对象,那么
  • 会让您的生活更轻松

当然,您可以通过覆盖initallocWithZone:来制作单独的单例,以返回唯一的实例或引发异常,但是我不确定它们是什么值得努力。

有关Misko Hevery在Google clean code talks播放列表中持有的单身人士的非常好的技术讲座,视频链接:here。这种单身人士在视频中被称为小写S单身,而不是资本S单身,Misko非常清楚地解释了为什么他们是首选。

答案 1 :(得分:0)

  1. 它并没有打破单身概念。您可以选择实施所需方式。如果只想创建单例实例,可以通过覆盖init函数使运行错误:

      [NSException exceptionWithName:NSInternalInconsistencyException
       reason:@"bla bla bla..." userInfo:nil];
    
    1. 您可以覆盖它以强制返回共享实例 当然可以。但如果您使用的是单身,则不建议使用。

答案 2 :(得分:-1)

Objective-C采用务实的方法。你的+ sharedManager方法返回一个单例。如果某人愚蠢到可以调用[SingletonClass new]或[[SingletonClass alloc] init],那就是他们的问题。他们会得到他们应得的。如果这是他们想做的事情,没有理由阻止人们在脚下射击。

人们可以制作数以百万计的编程错误,并且类或编译器的开发人员无法阻止。没有必要浪费精力来防止这种特殊错误。