Borut Tomazin
Borut Tomazin

Reputation: 8138

How to properly call singleton class on iOS

I have a singleton class named AppSettingsController with a few methods.

Generaly I call them like that:

[[AppSettingsController sharedInstance] myMethod];

And that's just fine.

This is how instance is created:

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

But I am considering something else. Let's assume I have to call myMethod in a loop. Wouldn't be better to create a local variable of this singleton and call this method with this variable?

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

... instead of calling it directly?

loop
  [[AppSettingsController sharedInstance] myMethod];

Which way is more efficient or are both equal?

Upvotes: 2

Views: 1506

Answers (4)

TheEye
TheEye

Reputation: 9346

IMHO it's a theoretical discussion for most cases - you won't feel the performance hit of having one level of indirection more when the sharedInstance is accessed every time in the loop instead of only once for setting a local variable before the loop.

Use the version you like most (readability wise) or if you do care about the performance hit then use the local variable way.

Upvotes: 2

Anoop Vaidya
Anoop Vaidya

Reputation: 46533

Go for second call

[[AppSettingsController sharedInstance] myMethod];

as this way is used by world and is more readable.

Upvotes: 1

Inder Kumar Rathore
Inder Kumar Rathore

Reputation: 39978

[[AppSettingsController sharedInstance] myMethod]; code will call two methods in a loop

and

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

will call only one

Here in 2nd case you are saving a single method call and thus 2nd one is more efficient. Also if in you sharedInstance method you have say 4 more method calls and some initialisation statements, then in that case you are saving that calls and initialisation statements too.


Update

Writing the sudo assembly code (using Sudo assembler :P). Just understand the idea don't go for exact assembly code

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:

Here clearly you can see what are you saving

Upvotes: 3

Andrea Mario Lufino
Andrea Mario Lufino

Reputation: 7921

In my opinion is better the first thing you do :

[[AppSettingsController sharedInstance] myMethod];

It is a singleton because it doesn't need to an instance. So, the first way is better. I think create an instance could use more memory than the direct call, but i'm not sure of this.

Upvotes: 1

Related Questions