使用Singleton作为另一个类的属性vs在每个方法中调用它

时间:2013-09-23 16:15:33

标签: objective-c design-patterns singleton

我问这个是Objective-C,因为我在那里使用它,但它可能适用于所有其他语言:

- 将单个引用引用到Obj-C属性是一件坏事吗?

- 在每个方法中调用共享实例会更好吗?

更精确:我有一个可以使用[MySingleton sharedInstance];

调用的单例类

我需要在另一个类MySecondClass中使用该单例的值50次,所以我创建了一个Obj-C属性

@property (nonatomic, strong) MySingleton *mySingletonProperty;

并通过调用

懒惰地在MySecondClass中初始化该属性一次
if(!self.mySingletonProperty)
{
    self.mySingletonProperty = [MySingleton sharedInstance];
}

我的一位朋友告诉我这是一个坏主意,最好不要使用单身人士来实现财产。正确的方法是在[MySingleton sharedInstance];的每个方法中调用MySecondClass并将其分配给局部变量。

这是对的吗?为什么?线程安全不是问题。

(请不要讨论在这里使用单身一般是不是一个坏主意 - 谢谢: - )

2 个答案:

答案 0 :(得分:3)

我经常看到的反复调用[SingletonClass sharedSingleton]的参数是消息传递(函数调用)开销。在这种情况下,在属性中存储对单例的引用具有相同的问题 - 始终调用self.singleton与调用[SingletonClass sharedSingleton]的函数调用数相同。

但这不是一个很好的论据,因为这种开销对性能的影响可以忽略不计。

相反,我会担心使用属性的语义含义。虽然通常假设单例模式在应用程序的生命周期中只有一个单例类的实例,但“标准”单例接口没有任何保证。如果您不拥有单例类,则可能会在具有strong属性的其他对象的生命周期内保留它,从而违反其设计假设。如果您拥有该类,那么保留对​​它的强引用会增加额外的设计约束,这些约束可能(但不太可能)以后会给您带来问题。

总之,我会提出以下建议。如果您的代码如下所示:

- someMethod {
    [[SingletonClass sharedSingleton] doSomething];
}
- someOtherMethod {
    [[SingletonClass sharedSingleton] doSomethingElse];
}

它没有任何问题。 (如果你真的想为自己节省一些打字,可能是[SingletonClass sharedSingleton]的本地预处理器宏是有序的。)

如果你有这样的代码:

- someMethod {
    [[SingletonClass sharedSingleton] doSomething];
    [[SingletonClass sharedSingleton] doSomethingElse];
    [[SingletonClass sharedSingleton] doSomeOtherThing];
    [[SingletonClass sharedSingleton] doYetAnotherThing];
}

然后,您可以通过将其存储在局部变量中来保存自己的一些输入(以及微不足道的性能成本)而无需语义更改:

- someMethod {
    SingletonClass *singleton = [SingletonClass sharedSingleton];
    [singleton doSomething];
    [singleton doSomethingElse];
    [singleton doSomeOtherThing];
    [singleton doYetAnotherThing];
}

答案 1 :(得分:-1)

如果你仍然需要一个单身人士,保持对它的引用并没有错。但为什么你把这个参考作为财产?我的建议是创建一个内部变量:

@interface MySecondClass : NSObject {
    // ...
    MySingleton *mySingletonInstanse;
}
// ...
@end