+(Service *) sharedInstance
{
static LocationService *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ <<<< Crash
instance = [[self alloc]init];
});
return instance;
}
I am using the above shown code to create a singleton instance of service in my application. This is called from "AppDelegate application:willFinishLaunchingWithOptions:".
For most of the users, this code works fine. But for 2 users, the app crashes at "dispatch_once(&onceToken, ^{ " line.
They deleted the app and re-installed it. But they still see the issue. Only these 2 users are facing this issue. Others have never seen it. I have the .dsym, .crash and other relevant files to do further debugging. Just wanted to know how should I proceed with it? If someone has seen similar issue how did they proceed with fixing it?
Don't use self. Because self is not available before the initilization of class. Instead you can use class name as follows.
+(Service *) sharedInstance
{
static LocationService *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[Service alloc]init];
});
return instance;
}
Related
There are different types of singleton implementation.
First:
static MyGlobalClass *instance = nil;
+(MyGlobalClass*)myinstance
{
#synchronized(self)
{
if(instance==nil)
{
instance= [MyGlobalClass new];
}
}
return instance;
}
Second:
+(PKShareClass *)sharedInstance
{
static PKShareClass *shaedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shaedInstance = [[PKShareClass alloc]init];
});
return shaedInstance;}
And finally with
static NSOperationQueue * _connectionQueue = nil;
+ (NSOperationQueue *) connectionQueue{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (!_connectionQueue)
{
_connectionQueue = [[NSOperationQueue alloc] init];
}
});
return _connectionQueue;
}
Here my question is what it means when we initialize like first and second ??
And third one with NSOperationQueue. What is the use when we initialize like third one?
Hard to find the meaning.
I'm afraid that i can't give you a link which can explain clearly about both 3 way but i will tell you what i understand.
First way: You create instance is a static variable of MyGlobalClass class. In myinstance method, you check if instance is initialized or not. If not, initialize instance. After all, return value of instance. Because instance is a static variable of MyGlobalClass so when you call [MyGlobalClass myinstance], it's always one object.
Second way: You create shaedInstance is a static variable of method sharedInstance. When you call dispatch_once(&onceToken, the code inside block is called only one time. About dispatch_once, you can take a look here. Because the initialization method is called only one time, shaedInstance is always one object when you return it. Actually, there is no different if shaedInstance is a static variable of PKShareClass class. You can use both 2 ways.
Third way: As you can understand after i explain about second way. This way is same like second way when shaedInstance is a static variable of PKShareClass class. But you don't need to check !_connectionQueue inside dispatch_once. Because it runs only one time and grossly it's always nil at the first time. This way can refactor like:
static NSOperationQueue * _connectionQueue = nil;
+ (NSOperationQueue *) connectionQueue{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (!_connectionQueue)
_connectionQueue = [[NSOperationQueue alloc] init];
});
return _connectionQueue;
}
Hope my answer can help you understand 3 ways easier ;)
This question already has an answer here:
What is the use of Singleton class in objective-c? [duplicate]
(1 answer)
Closed 7 years ago.
I am new to iOS development and I have gone through singleton class. I understood the concept, but having doubts in implementing the singleton class. Can anyone please share source code of the real time example using singleton class.
This is how a GCD for singleton class looks like.
Suppose there is a class that you made, MySingleTonClass which is a subclass of NSObject
MySingleTonClass.h
+(instanceType)sharedManager;
#property (nonatomic, strong) NSString *userName;
MySingleTonClass.m
+(instanceType)sharedManager{
static MySingleTonClass *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[MySingleTonClass alloc]init];
});
return manager;
}
Now you call this singleTon Class in some other class suppose in ViewController.m. First Import the Class
#import MySingleTonClass.h
-(void)viewDidLoad{
MySingleTonClass *manager = [MySingleTonClass sharedManager];
manager.userName = #"ABCDE";
//manager is the singleton Object
}
Edit
Now suppose you want to access this same value. then suppose in some other ViewController, after ViewController
Suppose in SecondViewController.m
#import "MySingleTonClass.h"
-(void)viewDidLoad{
MySingleTonClass *manager = [MySingleTonClass sharedManager];
NSLog (#"%#",manager.userName);
// This would still log ABCDE, coz you assigned it the class before, So even if you create a new object called manager here, it will return the same Manager you created before.
manager.userName = #"Myname"; //Now the value changed to MyName untill you change it again, in the lifetime of this application.
}
I hope i could make you understand the concept of it.
As you know, dispatch_once_t is a GCD snippet that makes the code inside of it invoke only ONCE per application run. Any code you write inside it will be run, or rather invoked only once in the lifetime of the application being active.
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)
[[self alloc] init];
return _sharedMySingleton;
}
return nil;
}
static User *defaultUser;
+ (User *)defaultUser
{
if (!defaultUser)
{
defaultUser = [self new];
// do something...
}
return defaultUser;
}
There are two ways:-
1) We can create singleton class using **GCD** dispatch_once
in this only one object will create if existing object is there then it will refer to them.
+(id)sharedManager
{
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
2) Second way is follows:-
+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
#synchronized(self) {
if (sharedMyManager == nil)
sharedMyManager = [[self alloc] init];
}
return sharedMyManager;
}
suppose this above method is written in class **MyManager** then u can use that as follow
MyManager *sharedManager = [MyManager sharedManager];
hope this will help u.
I have a singleton that is initialized like all singletons, with something like this:
+ (MySingleton *)sharedInstance
{
static MySingleton *sharedMyInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyInstance = [[MySingleton alloc] init];
});
return sharedMyInstance;
}
In my case I want to add some code to initialize the singleton but because sharedInstance is a class method I cannot call instance methods from there.
So I always have to have this pattern:
MySingleton *sing = [MySingleton sharedInstance];
[sing initialize];
Ok, I can do this
MySingleton *sing = [[MySingleton sharedInstance] initialize];
but this will generate another problem because if initializing the singleton is the only thing I want at this point, sing is not being used and this is ugly code.
I suppose I can do simply
[[MySingleton sharedInstance] initialize];
and Xcode will not complain, but this does not sound good.
Is there another way to do this?
Check your code ;-) Specifically the line:
sharedMyInstance = [[MySingleton alloc] init];
You have to implement init and there is where you'll initialize the instance variables of your singleton (AKA shared instance). It will be called the first time the shared instance is used.
I have a problem similar to this post, but that answer isn't working for me.
I have a singleton in my app which I used to create this way:
static POGalleryManager* defaultManager = nil;
+(POGalleryManager*)defaultManager
{
if (!defaultManager) {
defaultManager = [[super allocWithZone:NULL] init];
}
return defaultManager;
}
+(id)allocWithZone:(NSZone *)zone
{
return [self defaultManager];
}
This was working fine, so I tried to get clever and use GCD for thread safety, switching to this, which is supposed to be better:
+(POGalleryManager*)defaultManager
{
static POGalleryManager* __manager = nil;
dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
__manager = [[POGalleryManager alloc] init];
});
return __manager;
}
The first time this gets called, everything is fine. The second time it gets called like this:
[[POGalleryManager defaultManager] someMethod];
someMethod never gets called. I tried stepping into that line with the debugger and once it got to the dispatch_once line it just continued execution (ie. it kicked me out of the debugger - so maybe the thread died?).
Any advice on this?
Try to switch the
dispatch_once_t onceToken;
for
static dispatch_once_t onceToken;
How can I make a viewcontroller singleton, to then use this code:
FacebookManager *manager = [FacebookManager sharedManager];
[manager openSessionWithAllowLoginUI:NO]
??
That's not necessarily a singleton. A singleton can only have one instance at any given time. Shared instances are similar, but don't prevent additional instances from being created.
You can implement a shared instance with a static variable and a class method like this:
+ (FacebookManager *)sharedManager
{
static FacebookManager *shaderManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shaderManager = [[FacebookManager alloc] init];
});
return shaderManager;
}
Don't forget to declare the class method in your header.