How can I create a singleton class in Objective C?
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.
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.
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.
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)
...
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;
}
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.
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;
}
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/
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.
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
#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;
}
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;
}
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/
+ (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.
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With