23

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

@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 上帝?我敢肯定我不能成为第一个想到这个的人,但我保证,我先做了重复搜索。我发现的几个答案,我觉得是基于旧版本的可可,因为即使是讨论过的单例模式似乎也存在线程问题。

4

4 回答 4

20

静态类:当您想要将独立于状态的实用方法组合在一起时使用。

Singleton:当您有多个共享状态的方法时使用。

于 2013-08-17T01:12:14.153 回答
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];
于 2013-08-16T20:21:25.660 回答
1

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

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

于 2013-08-16T20:08:04.510 回答
1

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

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

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

static NSString* someStaticStateVariable;

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

这些函数可以在单独的 .h/.m 对中,或者可以合并到现有类的 .h/.m 中,如果这样做有意义的话(通常,如果函数与该类的关注点密切相关)。

于 2013-08-16T21:14:51.347 回答