Singleton Objective C | iOS

There are times when developing an application I need to have a single instance of a class. For example recently I needed to build an audio player that managed a song queue, and if the queue was playing. I also needed to be able to modify the queue from another view controller, so it was the perfect time to utilize the singleton pattern.

Singleton Pattern

In my example I am creating a singleton using an NSObject, this basic principle can be used on an type object. So lets take a look at the header file:

//
//  MySingleton.h
//
//  Created by Barrett A Breshears 
//

#import 

@interface MySingleton : NSObject

@property (nonatomic, retain) NSString *singletonValue;

+(MySingleton *)sharedMySingleton;

@end

Its a simple header file with a single NSString property and class method declaration. Now lets take a look at the implementation file.

//
//  MySingleton.m
//
//  Created by Barrett A Breshears
//

#import "MySingleton.h"

@implementation MySingleton

static MySingleton *_sharedMySingleton = nil;

+(MySingleton*)sharedMySingleton{
    @synchronized([MySingleton class]) {
        if (!_sharedMySingleton){
            _sharedMySingleton = [[self alloc] init];
        }
        return _sharedMySingleton;
    }
    return nil;
}

+(id)alloc {
    @synchronized([MySingleton class])
    {
        NSAssert(_sharedMySingleton == nil, @"Singleton already initialized.");
        _sharedMySingleton = [super alloc];
        return _sharedMySingleton;
    }
    return nil;
}

-(id)init {
    self = [super init];
    if (self != nil) {
        // initialize stuff here
    }   return self;
}
@end

First I declare a static instance of the MySingleton Class. Next I write my class method which checks to see if there is an instance of the singleton already created. If there isn’t it goes ahead and alloc and inits itself:

+(MySingleton*)sharedMySingleton{
    @synchronized([MySingleton class]) {
        if (!_sharedMySingleton){
            _sharedMySingleton = [[self alloc] init];
        }
        return _sharedMySingleton;
    }
    return nil;
}

You will notice that I’m using @synchronized inside of all the methods related to referencing allocating and initializing the singleton. Apple’s docs on threading are great. Take some time to read them if you want to learn more about threading and sycronization, but here is a sinpit that is important to what we are working on:

The presence of multiple threads in an application opens up potential issues regarding safe access to resources from multiple threads of execution. Two threads modifying the same resource might interfere with each other in unintended ways. For example, one thread might overwrite another’s changes or put the application into an unknown and potentially invalid state. If you are lucky, the corrupted resource might cause obvious performance problems or crashes that are relatively easy to track down and fix. If you are unlucky, however, the corruption may cause subtle errors that do not manifest themselves until much later, or the errors might require a significant overhaul of your underlying coding assumptions.

When it comes to thread safety, a good design is the best protection you have. Avoiding shared resources and minimizing the interactions between your threads makes it less likely for those threads to interfere with each other. A completely interference-free design is not always possible, however. In cases where your threads must interact, you need to use synchronization tools to ensure that when they interact, they do so safely.

So the @synchronized directive is an easy way to allow us to lock the object so it can’t be corrupted by multiple threads.

Next I set up my alloc class method and init instance method, again using @synchronized directive to lock the object.

+(id)alloc {
    @synchronized([MySingleton class])
    {
        NSAssert(_sharedMySingleton == nil, @"Singleton already initialized.");
        _sharedMySingleton = [super alloc];
        return _sharedMySingleton;
    }
    return nil;
}

-(id)init {
    self = [super init];
    if (self != nil) {
        // initialize stuff here
    }   return self;
}

And that’s it. We can use the MySingleton class like this:

[MySingleton sharedMySingleton].singletonValue = @"Sledge Dev";

Using Singletons

The singleton is first pattern I learned when I start object oriented programming a long time ago. I really like it, and am probably guilty of overusing it myself. I have read a lot about how it not such a great idea to use a singleton, there are a ton of great articles out there if you want more info about this subject. Here are a couple of my favorites:

Personally I think there is a time and a place to use them, but please let me know what you think in the comments down below.

Author: barrettbreshears

I don't take showers, only blood baths.

1 thought on “Singleton Objective C | iOS”

Comments are closed.