如何在iOS上正确调用singleton类

时间:2013-02-21 14:26:25

标签: iphone ios singleton shared

我有一个名为AppSettingsController的单例类,有一些方法。

通常我称之为:

[[AppSettingsController sharedInstance] myMethod];

这很好。

这是创建实例的方式:

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

但我正在考虑别的事情。我们假设我必须在循环中调用myMethod。创建这个单例的局部变量并用这个变量调用这个方法不是更好吗?

AppSettingsController *mySharedInstance = [AppSettingsController sharedInstance];
loop
  [mySharedInstance myMethod];

...而不是直接调用它?

loop
  [[AppSettingsController sharedInstance] myMethod];

哪种方式更有效或两者相同?

4 个答案:

答案 0 :(得分:3)

[[AppSettingsController sharedInstance] myMethod];代码将在循环中调用两个方法

  

AppSettingsController * mySharedInstance = [AppSettingsController sharedInstance];   

  [mySharedInstance myMethod];

只会拨打一个

在第二种情况下,您将保存单个方法调用,因此第二个更有效。此外,如果您使用sharedInstance方法,您已经说4个方法调用和一些初始化语句,那么在这种情况下您也会保存这些调用和初始化语句。


更新

编写sudo汇编代码(使用Sudo汇编程序:P)。只要明白不要使用精确汇编代码的想法

Case 1:
Loop start:
1 Call method sharedInstance

  [this code step 2-7 will be called only once]
  2 Create a static AppSettingsController *sharedInstance = nil; in sharedInstance method
  3 Create static dispatch_once_t onceToken;
  4 Call dispatch_once
  5 Now dispatch_once takes lock of onceToken (and other task which is not visible for me)
  6 Call [self alloc]
  7 Call [self init]

8 Return from sharedInstance
9 Call myMethod
Loop ends:




Case 2:
1 Call method sharedInstance
2 Create a static AppSettingsController *sharedInstance = nil; in sharedInstance method
3 Create static dispatch_once_t onceToken;
4 Call dispatch_once
5 Now dispatch_once takes lock of onceToken (and other task which is not visible for me)
6 Call [self alloc]
7 Call [self init]
8 Return from sharedInstance
9 Assign sharedInstance value to mySharedInstance variable
Loop starts:
10 Call myMethod
Loop Ends:

这里显然你可以看到你在节省什么

答案 1 :(得分:2)

对于大多数情况来说,这是一个理论上的讨论 - 当你在循环中每次访问sharedInstance而不是只在循环之前设置一个局部变量时,你不会感觉到更多间接性的性能受到影响。

使用您最喜欢的版本(可读性)或者如果您关心性能命中,请使用局部变量方式。

答案 2 :(得分:1)

在我看来,你做的第一件事情更好:

[[AppSettingsController sharedInstance] myMethod];

它是一个单例,因为它不需要实例。所以,第一种方式更好。我认为创建一个实例可以使用比直接调用更多的内存,但我不确定这一点。

答案 3 :(得分:1)

进行第二次通话

[[AppSettingsController sharedInstance] myMethod];

因为这种方式被世界使用并且更具可读性。