46

How can I create a singleton class in Objective C?

iOSAppDev
  • 2,755
  • 4
  • 39
  • 77
  • Possible Duplicate: http://stackoverflow.com/questions/3911042/objective-c-proper-way-to-create-class-with-only-one-instance – Richard J. Ross III Mar 21 '11 at 17:10
  • See : [Objective-c singleton](http://stackoverflow.com/questions/145154/what-does-your-objective-c-singleton-look-like) – Michaël Mar 21 '11 at 17:11

14 Answers14

58

Okay appDev, you will probably find quite a few different techniques to do this on the web. However, for iOS app development, I think the most convenient way is to do the following:

  • Write your method(s) for getting the singleton object. (Recommendation: use dispatch_once thread and GCD for this).

  • Wrap your method(s) in a macro and add it to your $Project$-Prefix.pch file.

  • Call the one line macro whenever you need singleton object for a class.

Example:

CommonMacros.h:

#define SINGLETON_FOR_CLASS(classname)
+ (id) shared##classname {
    static dispatch_once_t pred = 0;
    static id _sharedObject = nil;
    dispatch_once(&pred, ^{
        _sharedObject = [[self alloc] init];
    });
    return _sharedObject;
}

YourProject-Prefix.pch:

...
#import "CommonMacros.h"
...

YourSingletonClass.m:

...
SINGLETON_FOR_CLASS(YourSingletonClass)
...
Alberto M
  • 1,608
  • 1
  • 18
  • 42
John Doe
  • 2,173
  • 1
  • 21
  • 12
  • 2
    http://weblog.highorderbit.com/post/11656225202/appropriate-use-of-c-macros-for-objective-c-developers – clopez Sep 26 '12 at 13:55
29

Check out this link for the original source - http://getsetgames.com/2009/08/30/the-objective-c-singleton/

@implementation MySingleton
static MySingleton *_sharedMySingleton = nil;

+(MySingleton *)sharedMySingleton {
    @synchronized([MySingleton class]) {
        if (!_sharedMySingleton)
          _sharedMySingleton = [[self alloc] init];
        return _sharedMySingleton;
    }
    return nil;
}
Nagarjun
  • 6,557
  • 5
  • 33
  • 51
Sachin Shanbhag
  • 54,530
  • 11
  • 89
  • 103
  • 7
    This is nice, but the assignment is missing: _sharedDataModel = [[self alloc] init]; – Chuck H Jul 22 '13 at 04:34
  • @ChuckH: Doesn't self represent _sharedMySingleton? – Chandu May 14 '14 at 18:14
  • 1
    @Chandu: In the example above, self does not refer to an instance of the MySingleton class, it refers to to the MySingleton class object. If compiled as-is, the compiler will give a warning that the result of the [[self alloc] init] expression is not used. However, the above example only works because the link to the original source also included an alloc class method which ended up doing the needed assignment. I think it would be much easier to eliminate the alloc class method and do the static variable assignment directly with the results of the alloc/init of the singleton instance. – Chuck H May 14 '14 at 22:31
  • the url is obsolete – iosMentalist Oct 23 '19 at 14:30
23

I do think this is how we can truly achieve singleton behavior :

@interface SampleSingletonClass : NSObject

+ sharedSampleSingletonClass;

@end


@implementation SampleSingletonClass
static SampleSingletonClass *singletonObject = nil;

+ (id) sharedSampleSingletonClass
{
    if (! singletonObject) {

        singletonObject = [[SampleSingletonClass alloc] init];
    }
    return singletonObject;
}

- (id)init
{
    if (! singletonObject) {

        singletonObject = [super init];
    // Uncomment the following line to see how many times is the init method of the class is called
    // NSLog(@"%s", __PRETTY_FUNCTION__);
    }
    return singletonObject;
}

@end

Here even if one calls init method instead of the intended + (id) SampleSingletonClass; method the actual object is formed just once throughout the app's lifecycle.

Abhijit
  • 461
  • 4
  • 6
13

This is my personal favourite way to do it:

+ (instancetype)sharedObject {
    static id instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}
Chris
  • 39,719
  • 45
  • 189
  • 235
12

You can implement a singleton class in Objective-C .

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

- (id)init {
  if (self = [super init]) {
      someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
  }
  return self;
}

http://www.galloway.me.uk/tutorials/singleton-classes/

Amulya
  • 182
  • 1
  • 12
  • 2
    Note that [link-only answers](http://meta.stackoverflow.com/tags/link-only-answers/info) are discouraged, SO answers should be the end-point of a search for a solution (vs. yet another stopover of references, which tend to get stale over time). Please consider adding a stand-alone synopsis here, keeping the link as a reference. – kleopatra Oct 16 '13 at 09:53
7

From: http://www.galloway.me.uk/tutorials/singleton-classes/

Singletons in Objective-C

One of my most used design patterns when developing for iOS is the singleton pattern. It’s an extremely powerful way to share data between different parts of code without having to pass the data around manually.

Background

Singleton classes are an important concept to understand because they exhibit an extremely useful design pattern. This idea is used throughout the iPhone SDK, for example, UIApplication has a method called sharedApplication which when called from anywhere will return the UIApplication instance which relates to the currently running application.

How to implement

Singletone.h

#import <foundation/Foundation.h>

@interface Singleton : NSObject {
}

 @property (nonatomic, retain) NSString *someProperty;

  + (id)sharedManager;

 @end

Singleton.m

#import "Singleton.h"

@implementation Singleton

@synthesize someProperty;

#pragma mark Singleton Methods

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

 - (id)init {
  if (self = [super init]) {
     someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
  }
return self;
}

@end

What this does is it defines a static variable (but only global to this translation unit)) called sharedMyManager which is then initialised once and only once in sharedManager. The way we ensure that it’s only created once is by using the dispatch_once method from Grand Central Dispatch (GCD). This is thread safe and handled entirely by the OS for you so that you don’t have to worry about it at all.

Koen.
  • 25,449
  • 7
  • 83
  • 78
Mannam Brahmam
  • 2,225
  • 2
  • 24
  • 36
  • Sir Why is it that **Class *classObj = nil;** this means pointer object is not pointing to anything in memory. And what exactly this static keyword is doing here, Kindly explain. – Ritesh.mlk Apr 18 '17 at 09:14
  • More over **"nil is used to represent a null pointer to an Objective-C object. Nil is used to represent a null pointer to an Objective-C class."** So sharedMyManager is Objective-C Object or Class object. But I believe sharedMyManager is an pointer Object which points to the Singleton Class. – Ritesh.mlk Apr 18 '17 at 09:20
4

Try this

Singalton class .h file

#import <Foundation/Foundation.h>

@interface GlobleDirector : NSObject
+(GlobleDirector*)shareManager;
@end

Singalton class .m file

#import "GlobleDirector.h"

@implementation GlobleDirector


+(GlobleDirector*)shareManager{

static GlobleDirector *sharedInstance=nil;
static dispatch_once_t  oncePredecate;

dispatch_once(&oncePredecate,^{
    sharedInstance=[[GlobleDirector alloc] init];

 });
return sharedInstance;
}



@end
2

This is the right way to create the singleton Class

mySingletonClass.h

@interface mySingletonClass : NSObject

 + (mySingletonClass*)sharedInstance;
 @property (nonatomic, assign)BOOL      useToken;



mySingletonClass.m

@implementation mySingletonClass

static mySingletonClass *_sharedInstance = nil;


+ (mySingletonClass*)sharedInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[self alloc] init];

    });

    return _sharedInstance;
}

How to access singleton class properties or methods in anothor class

anotherClass.m

Bool isTokenValid = [mySingletonClass sharedInstance].useToken;
Shubham JAin
  • 593
  • 8
  • 15
1
    static DBHandler* sDBHandler = nil;

- (id)init
{
    self = [super init];
    if (self) {
        [self checkAndCreateDatabase];
    }
    return self;
}

+(id)sharedDBHandler
{
    @synchronized (self) {
        if (sDBHandler == nil) {
            sDBHandler = [self new];
        }
    }
    return sDBHandler;
}
Rijo Payyappilly
  • 801
  • 8
  • 12
1

I know it is supposed visitors know what is a singleton but in order to help those they don't, I propose this simple little example with shared data.

The object is used to shared data classes instances or class(es) instances.

@interface SharedData : NSObject {
    id data;
}
- (void)setData:(id)data_;
- (id)data;
@end

@implementation SharedData
//>> singleton
static SharedData *sharedData=nil;
+ (SharedData*)sharedData {
    @synchronized (self) {
        if (sharedData==nil) sharedData=[[self alloc]init];
    }
    return sharedData;
}
//<<
- (void)setData:(id)data_ {
    data=data_;
}
- (id)data {
    return data;
}
@end

... The 1st call (+ sharedData) instantiate the object basing his reference on static (locale shared) variable that it returns as instance ref. The next call only returns reference to the static variable.

The data can be set/get at any time with embedded accessor.

It results a relative simplification to share an object but it is possible to process "manually" by reference sharing.

@synchronized is just needed for multithreading. For simple class(es) instances sharing it's not needed.

An extended explanation here: http://www.galloway.me.uk/tutorials/singleton-classes/

Luc-Olivier
  • 3,715
  • 2
  • 29
  • 29
1
#import <Foundation/Foundation.h>

@interface singt : NSObject  

+ (id)sharedManager;

@end


#import "singt.h"

@implementation singt


+ (id)sharedManager 

{

    static singt *sharedMyManager = nil;
     static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];


    });

    return sharedMyManager;

}
Tim Malone
  • 3,364
  • 5
  • 37
  • 50
  • Hi Acharya, welcome to SO and thank you for your answer. Code only answers are discouraged here as they can be hard for others to understand and learn from. Do you think you could edit your answer to explain why this solves the OP's problem? Thanks very much. – Tim Malone Jun 20 '16 at 05:28
1

Please try below code.

@implementation AppShared
static AppShared *singletonInstance;

+ (AppShared*)Instance{
if (singletonInstance == nil) {
    singletonInstance = [[super alloc] init];
}
return singletonInstance;
}
xMRi
  • 14,982
  • 3
  • 26
  • 59
1
+ (id)sharedInstance {
    static dispatch_once_t pred = 0;
    __strong static id _sharedObject = nil;
    dispatch_once(&pred, ^{
        _sharedObject = [[self alloc] init];
    });
    return _sharedObject;
}

- (id)init {
    self = [super init];
    if (self) {
    }
    return self;
}

And add in the .h

+ (id)sharedInstance;

PD: your class should inherit from NSObject .

Remember to call always the sharedinstance when you want to use it, not to call init.

Cristik
  • 30,989
  • 25
  • 91
  • 127
Pablo Blanco
  • 679
  • 8
  • 14
-2

In swift 1.2 or later, if classname is eg: singletonVC

class singletonVC {

    static let sharedMySingleton = singletonVC()

    private init(){ 
    }

}

Implementation:

singletonVC.sharedMySingleton.yourFunctionName
Mamun
  • 66,969
  • 9
  • 47
  • 59
Vimal
  • 187
  • 6