GCD-style Singleton throws compile error... sometimes? - objective-c

I'm implementing the textbook-singleton in Objective-C:
+ (instancetype) sharedSingleton
{
id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
...as I have been doing for a while. When changing an old #synchronized-syntax singleton to this kind, in an old project (open in the latest version of Xcode), I get the error:
Variable is not assignable (missing __block type specifier)
...pointing at the allocation line. I have the exact same code in many parts of other code, built and run with the same environment, and never an issue... What's going on? Should I prepend the __block qualifier and be done with it, or is there more than meets the eye here?
The only thing I can think of is, this old project I'm modernising right now has NOT been transitioned to ARC... (yet)

You are missing static on the sharedInstance variable. That line should be
static id sharedInstance = nil;
Colin Wheelas has a good and short article about how to create singeltons using dispatch_once.

Related

Are my Objective-C singletons thread safe?

I've been reading around and its hard to get a clear feel if I have written a thread safe implementation here.
My getter looks like
+ (MySingleton *)getSingleton
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[MySingleton alloc] init];
});
return singleton;
}
And my setter is:
+ (void)updateSingleton:(MySingleton *)newSingleton
{
#syncronized(self) {
singleton = newSingleton;
}
}
No, that isn't thread safe. Your exclusion mechanism between your two modification methods are not the same. dispatch_once has nothing to do with #synchronized in any way.
Beyond that a singleton must never be replaced by definition. A singleton can come into existence at any time and, once it does, it never, ever, goes away.
Also, getSingleton should be sharedInstance or some similar objective-c standard moniker. Methods should never be prepended with get unless they are returning stuff by reference.

dispatch_once vs runtime check for once initialized property

What is the difference between dispatch_once and using runtime conditional check for the property that requires only once initialization
Method 1: runtime checking
- (MyProp *)myProp{
if (!_myProp){
_myProp = [[MyProp alloc] init];
}
return _myProp;
}
Method 2: use dispatch_once
- (MyProp *)myProp{
dispatch_once_t once;
dispatch_once(&once, ^{
_myProp = [[MyProp alloc] init];
}
return _myProp;
}
I guess that method 2 is somehow faster but not really sure.
Could anyone give me any deal?
Thanks
dispatch_once is thread safe. So if two threads call myProp for the first time simultaneously, dispatch_once ensures only one initializes the variable. Method 1 may initialize the variable twice, and could even corrupt memory such that the reference is invalid. Once the property has been initialized, these behave identically.
Method 2 is actually slightly slower than Method 1, particularly during the first initialization. But in the usual case (reading after initialization), it is extremely close (possibly identical) in performance. If you want a much more in-depth exploration of how it works and why, see Mike Ash's Secrets of dispatch_once.
Note that your Method 2 code is incorrect. You've made once an automatic local variable. It needs to be static or dispatch_once can't do its job. What you meant was:
- (MyProp *)myProp{
static dispatch_once_t once; // <--- this "static" is critical
dispatch_once(&once, ^{
_myProp = [[MyProp alloc] init];
}
return _myProp;
}

Can I make single-instance classes in Objective-C? [duplicate]

This question already has answers here:
Create singleton using GCD's dispatch_once in Objective-C
(10 answers)
Closed 7 years ago.
What I want to create:
I want to make a class that has a shared instance of itself. When I call [someClass sharedInstance];, I want to have it return just that: a shared instance of itself.
The reason is this: I want to have a class in my app that can handle a bunch of methods that I would need to call a bunch of times, or get values of. For example, I want a class that can access motion data using CoreMotion from the data's gyroscope and have it be read correctly in any orientation.
I know, in landscape, the X and Y values are swapped if you're making the update change the Euler angles of a SceneKit camera node.
If I want to make a bunch of scenes, I'd have to create many instances of this motion manager class, and have it load with each scene. That can be avoided with only making one instance of said motion manager, starting it up, and then getting/returning values every so often.
My problem is:
How would I go about coding a class method call so it will return the class's shared instance? I know the method call would be +(instancetype)sharedInstance in the class's .h/.m files, but I don't know how to get it to return said shared instance.
Also, how would I initialize the shared instance?
Edit note: The question it is apparently a duplicate of is NOT a duplicate of this question; that question is about whether or not GCD's dispatch_once is the best way of doing it in iOS 4.0. Most devices nowadays don't use iOS 4.0, and 4.0 is very well obsolete.
Absolutely. This is the singleton pattern I've always used for objective-c
+ (instancetype)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
and here's one for if you want your singleton to be achievable and will unwrap the achieved instance if one exists:
+ (instancetype)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSArray *archivePathHeader = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *archivePathToDocuments = [archivePathHeader objectAtIndex:0];
NSString *filePathOfArchive = [archivePathToDocuments stringByAppendingPathComponent:#"[FILE NAME]"];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePathOfArchive]) {
sharedMyManager = [NSKeyedUnarchiver unarchiveObjectWithFile:filePathOfArchive];
} else {
sharedMyManager = [[self alloc] init];
}
});
return sharedMyManager;
}
Both of these use the GCD.
you can call them like so:
sharedSettings = [Settings sharedSettings];

Proper Singleton Implementation

I'm reading through a book trying to brush the dust off of Objective-C, and I ran into this question while reading how to implement a singleton. This is the implementation as they have it in the book:
+ (ClassName *)sharedClass {
static ClassName *sharedClass = nil;
if (!sharedClass) {
sharedClass = [[super allocWithZone:nil] init];
return shared store
}
My question is, why would they set it to nil each time the method is ran, then check if it's nil, which it now obviously is, and create a new instance? That sounds like it defeats the whole purpose of a singleton, to only have one instance of a class. I've noticed a ton of questions related to singleton implementation, but none specific to this aspect of it. Believe me, I combed through before posting.
The static variable is set to nil only for the first time. Once the sharedClass instance is instantiated, you will alway have the same instance whenever you invoke [ClassName sharedClass].
You should use thread-safe pattern to use singleton pattern.
+ (instancetype)shared {
static id shared = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shared = [[self alloc] init];
});
return sharedInstance;
}
This will prevent possible crashes.

Singletons objective C

I have a NSString *date. I fetch some data from the internet and now I have the date I want in this variable. I want to be able to use this NSString at anytime without calling a method that returns it at any scope within my program.
Where would I put the code to retrieve the date from the internet that the variable will hold? Would it be here? and then would I eventually make date= sharedInstance?
static SingletonClass *sharedInstance = nil;
// Get the shared instance and create it if necessary.
+ (SingletonClass *)sharedInstance
{
if (sharedInstance == nil) {
sharedInstance = [[super allocWithZone:NULL] init];
}
//Do I Put Code here?????
return sharedInstance;
}
Thanks in advance!
If you really want to use a singleton pattern and can target an OS with GCD, then dispatch_once can simplify your singleton code, e.g.
+ (id)sharedFoo
{
static dispatch_once_t pred;
static Foo *foo = nil;
dispatch_once(&pred, ^{ foo = [[self alloc] init]; });
return foo;
}
Depending on your requirements, you can override the init method to provide whatever additional initialization you need.