brainray
brainray

Reputation: 12884

Using a Singleton as property of another class vs calling it in every method

I'm asking this for Objective-C because I use it there, but it might apply for all other languages:

-is it a bad thing to have a reference of a single to a Obj-C property?

-Would it be better to call the shared instance in every method?

More precise: I have a singleton class that I can call by using [MySingleton sharedInstance];

I need values of that singleton like 50 times in another class MySecondClass So I created a Obj-C property

@property (nonatomic, strong) MySingleton *mySingletonProperty;

and lazily initialize that property once in MySecondClass by calling

if(!self.mySingletonProperty)
{
    self.mySingletonProperty = [MySingleton sharedInstance];
}

A friend of mine told me this would be a bad idea, and it would be better not to use a singleton to instanciate a property. The right way would be to call [MySingleton sharedInstance]; in every method of MySecondClass and assign it to a local variable.

Is that correct? And why? Thread safety is not an issue.

(Please don't discuss if it's a bad idea using a singleton in general here - thanks:-)

Upvotes: 0

Views: 585

Answers (2)

maxibystro
maxibystro

Reputation: 25

If you still need a singleton there is nothing wrong with keeping a reference to it. But why do you keep the reference as a property? My advice is to create an internal variable:

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

Upvotes: -2

rickster
rickster

Reputation: 126157

The argument I usually see against repeatedly calling [SingletonClass sharedSingleton] is message-passing (function call) overhead. In that case, stashing a reference to your singleton in a property has the same problem -- calling self.singleton all the time is the same number of function calls as calling [SingletonClass sharedSingleton].

That's not a great argument, though, because such overhead has negligible performance impact.

Instead, I'd be concerned about the semantic implications of using a property. While it's generally an assumption of the singleton pattern that there is only one instance of the singleton class over the lifetime of your app, nothing about the "standard" singleton interface guarantees that. If you don't own the singleton class, you may violate its design assumptions by retaining it over the lifetime of some other object with a strong property. If you do own that class, keeping a strong reference to it adds extra design constraints that may (however unlikely) cause problems for you later on.

In summary, I'd give the following advice. If you have code that looks like this:

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

There's nothing wrong with it. (If you really want to save yourself some typing, maybe a local preprocessor macro for [SingletonClass sharedSingleton] is in order.)

If you have code like this:

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

Then you can save yourself a bit of typing (and trivial performance cost) without semantic changes by stashing it in a local variable:

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

Upvotes: 3

Related Questions