2013-08-16 102 views
21

所以,很简单的问题。忽略过度使用单例模式的影响。我试图在Objective-C中找到一个可靠的单例模式。我也碰到过这样的:Static Class vs Singleton

@implementation SomeSingleTonClass 

static SomeSingleTonClass* singleInstance; 

+ (SomeSingleTonClass*)getInstance 
{ 
    static dispatch_once_t dispatchOnceToken; 

    dispatch_once(&dispatchOnceToken, ^{ 
     singleInstance = [[SomeSingleTonClass alloc] init]; 
    }); 

    return singleInstance; 
} 

- (void)someMethodOnTheInstance 
{ 
    NSLog(@"DO SOMET WORK") 
} 

@end 

这个我有非常愉快的,但它导致了很多本:

[[SomeSingleTonClass getInstance] someMethodOnTheInstance]; 

我的问题是,为什么这不是一个纯粹的静态类更好。

@implementation SomeStaticClass 

static NSString* someStaticStateVariable; 

- (id)init 
{ 
    //Don't allow init to initialize any memory state 
    //Perhaps throw an exception to let some other programmer know 
    //not to do this 
    return nil; 
} 

+ (void)someStaticMethod 
{ 
    NSLog(@"Do Some Work"); 
} 

所有你真正获得的,是轻度更清洁的寻找方法调用。基本上你换出这一点:

[[SomeSingleTonClass getInstance] someMethodOnTheInstance]; 

对于这个

[SomeStaticClass someStaticMethod]; 

这是肯定的未成年简化,可以随时存储您的类中的实例。这是更多的智力好奇心,我使用静态类而不是单身人士嘲笑Objective-C神吗?我确信我不能成为第一个想到这个问题的人,但我保证,我首先做了重复搜索。我发现的答案很少,我觉得是基于老版本的可可,因为即使讨论的单例模式似乎也受到线程问题的困扰。

+0

我认为你是对的,但问题是有点儿费解(虽然答案是固体!)。我将要离开我的,但在该主题中给出答案后,我不需要等待Drummer的回答上的提示。这是正确的。谢谢! – ChrisCM

+0

什么是静态类? – Monolo

+0

静态类(可能有更好的名称)是一个依赖类方法和静态类变量的类,而不是实例化的对象和实例方法。这是什么使它成为一个方便的单身人士。特别是如果你编写你的init方法来抛出异常! – ChrisCM

回答

1

你没有像这样的课堂上没有Objective-C的神。实际上,苹果建议在某些情况下使用这种模式(我认为他们在ARC会话视频中提到了这一点,他们讨论了常见的设计模式以及如何使用ARC来实现它们)。

在其他情况下,如果您可以拥有一个类的多个实例,但想要一个默认实例,那么您当然必须使用共享实例方法。

+0

基本正确。此外,请参阅Martin提供的“重复”链接中的答案以应对每个问题的影响。看起来两种方法都不是更好或更差,只是不同而已。 – ChrisCM

+2

一件事,没有人指出的是,一个不平凡的单身(而不是一个静态类)可以做很多更多的东西,因为它是一个合法的实例。注册通知,将键 - 值观察,用作数据源等 –

+0

当你说“这种模式”,受诅咒的模式你在说什么哪?大声笑。他在帖子中提出了两种不同的模式。 – TheJeff

3

我发现很容易做到两者兼而有之。我使用类似标准的单例模式你先说结果:

[[MyClass defaultInstance] doSomething]; 

但我也希望能够创造同一类的其他实例:

MyClass *secondInstance = [[MyClass alloc] init]; 
[secondInstance doSomething]; 

当我想更简洁访问打电话的单实例的方法,我定义类方法如下:

// class method to call a method on the singleton instance 
+ (void)doSomething 
{ 
    [[MyClass defaultInstance] doSomething]; 
} 

因此,与这一点,我可以使用:

[MyClass doSomething]; 
1

第一个例子似乎是不必要地创建类的单例类实例。我不必要地说,因为从其他评论看来,该类不声明任何属性或实例变量。鉴于对象的基本目的是为状态提供存储,没有实例变量的对象很少有用。

你的第二个例子显示了一个永远不会被实例化的类。同样,Objective-C中的类的基本目的是充当实例的工厂,所以从未实例化的类不是真正有用或必需的。

相反,您可以只提供一组C函数。 C函数根本不需要与类关联。因此,考虑做这样的事情:

static NSString* someStaticStateVariable; 

void someFunction(void) 
{ 
    NSLog(@"Do Some Work"); 
} 

的功能可以是单独的.h/.M对,或者可以在.H/.M被合并为现有的类,如果它是有道理这样做(一般来说,如果功能与该类别的关注密切相关)。

+0

该班的演示是为了演示我只考虑的设计模式,而不是我为他们考虑的使用。为了解决堆栈溢出的问题,当然我期望我的类具有比我在简化示例中提供的更多的状态。 – ChrisCM

+0

@ChrisCM你似乎在说你的情况下,将有状态,但在你的第二个例子,你覆盖'init'禁用创建实例,所以很明显没有具有状态对象的可能性。你不能为类添加状态,所以剩下的就是全局变量。同样,你不需要类和方法来使用全局变量,那么为什么不使用C函数呢? – jlehr

+0

我想最终它不回答这个问题。两种解决方案都有可能存在相同的缺陷,即将状态存储在静态全局变量中。这是“为什么/为什么不?”我很好奇,而不是如何。那么,为什么不使用普通的C函数呢?因为将某些东西与类关联起来对于更清楚地理解代码本质上是有用的。 [MyDatabaseClass someFunction]告诉我更多关于someFunction()的内容。 – ChrisCM

16

静态类:用于当你想组合在一起的实用方法是独立的国家。

单身人士:当您有多个共享状态的方法时使用。