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

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

Related

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.

Difference creating Singleton by class method and instance method

What are the implications of creating a singleton class with:
+ (id)sharedCoordinator {
static MyCoordinator *sharedCoordinator = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedCoordinator = [[self alloc] init];
});
}
or as an instance method in the Application Delegate with class method:
- (CoreDataHelper *)cdh {
if (!_coreDataHelper) {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
_coreDataHelper = [CoreDataHelper new];
});
[_coreDataHelper setupCoreData];
}
return _coreDataHelper;
}
I have seen them both used, and would like to learn how they affect performance, simple code, debugging, etc.
The main difference is that the second code snippet has an error: when cdh is accessed concurrently from multiple threads, there is a possibility of [_coreDataHelper setupCoreData] being called twice.
This would happen if multiple threads arrived at cdh at the time when _coreDataHelper is nil. Only one of these threads would proceed to make the [CoreDataHelper new] call, yet all threads would end up in the setupCoreData method.
The proper way of doing initialization is to place the setup call into the block, and make the call unconditional:
- (CoreDataHelper *)cdh {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
_coreDataHelper = [CoreDataHelper new];
[_coreDataHelper setupCoreData];
});
return _coreDataHelper;
}
Now the two snippets look almost identical. The only difference is that the first snippet uses a method-static variable to store the singleton, while the updated second snippet "piggybacks" on the instance of app delegate.
This does not create any performance differences worth discussing. The biggest difference is that the first snippet lets you access the singleton without creating an additional dependency on the app delegate, which is a good thing: this avoids "polluting" your app delegate with code that is not directly relevant to the application state.
The first allows the Singleton class to be re-used in other places.
The second makes the single instance private to the app delegate.
Generally the first option is better (IMHO.) It allows you to reuse the single instance in a structured way anywhere in your code.
The second option can provide a guarantee of being a single instance, privately accessible in one place. That is probably useful in some circumstances, but it isn't really a Singleton. You could make this a public property on the AppDelegate, but then why not use a Singleton class?
As for performance considerations, they should be negliable. The only one I can think of is the slight extra overhead in the runtime caused by having an extra class object in your code.

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

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.

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.

Check if object exists - Objective C

Instead of recreating an object over and over again, is there a way I can check if an object exists in an if statement?
Thanks!
Assuming your object reference is set to nil if there is no object, then you can use
NSThing *myobj = nil;
if (!myobj)
myobj = [[NSThing alloc] init];
[myobj message];
Depends on your situation. You could use a static variable, i.e.
- (void) doSomething
{
static id foo = nil;
if (! foo)
foo = [[MyClass alloc] init];
// Do something with foo.
}
The first time -doSomething gets called, MyClass will be instantiated. Note that this isn't thread-safe.
Another way is to use a singleton. Possibly a better way is to instantiate the object when the application has finished launching and pass the object to any other objects that might need it.
The thread safe common way to initialize some instance using GCD is as follows:
static dispatch_once_t once;
dispatch_once(&once, ^{
obj = [NSSomeThing new];
});