Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create singleton class in objective C

How can I create a singleton class in Objective C?

like image 421
iOSAppDev Avatar asked Mar 21 '11 17:03

iOSAppDev


People also ask

When to use singleton design pattern?

It is used where only a single instance of a class is required to control the action throughout the execution. A singleton class shouldn't have multiple instances in any case and at any cost. Singleton classes are used for logging, driver objects, caching and thread pool, database connections.

Why singleton?

A singleton should be used when managing access to a resource which is shared by the entire application, and it would be destructive to potentially have multiple instances of the same class. Making sure that access to shared resources thread safe is one very good example of where this kind of pattern can be vital.

What is a singleton in programming?

A singleton is a class that allows only a single instance of itself to be created and gives access to that created instance. It contains static variables that can accommodate unique and private instances of itself. It is used in scenarios when a user wants to restrict instantiation of a class to only one object.


12 Answers

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)
...
like image 74
John Doe Avatar answered Sep 22 '22 23:09

John Doe


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;
}
like image 45
Sachin Shanbhag Avatar answered Sep 21 '22 23:09

Sachin Shanbhag


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.

like image 27
Abhijit Avatar answered Sep 21 '22 23:09

Abhijit


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;
}
like image 21
Chris Avatar answered Sep 21 '22 23:09

Chris


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/

like image 24
Amulya Avatar answered Sep 19 '22 23:09

Amulya


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.

like image 33
Mannam Brahmam Avatar answered Sep 20 '22 23:09

Mannam Brahmam


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
like image 20
Rajkumar Yadav Avatar answered Sep 22 '22 23:09

Rajkumar Yadav


#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;

}
like image 27
Acharya Ronak Avatar answered Sep 21 '22 23:09

Acharya Ronak


    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;
}
like image 40
Rijo Payyappilly Avatar answered Sep 20 '22 23:09

Rijo Payyappilly


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/

like image 35
Luc-Olivier Avatar answered Sep 19 '22 23:09

Luc-Olivier


+ (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.

like image 22
Pablo Blanco Avatar answered Sep 23 '22 23:09

Pablo Blanco


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;
like image 27
Shubham JAin Avatar answered Sep 22 '22 23:09

Shubham JAin