-1

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.

Community
  • 1
  • 1
DDPWNAGE
  • 1,423
  • 10
  • 37
  • @NicolasMiari that question explains the **process** behind creating a singleton object. Your linked question is about whether or not a method of creating a singleton object (in that case, GCD's `dispatch_once`) is the best way to go about doing it. The question was the answer to my question. It is not a duplicate question. – DDPWNAGE Aug 10 '15 at 01:15
  • 1
    You asked how to implement a class that can be instantiated only once (like `UIDevice`, `NSFileManager`, etc.). That is the **singleton pattern**, and this has been asked a thousand times. Some years ago, the preferred method was using the `@synchronize` directive, or the class method `+initialize` (gets called once). The answer I linked contains the currently accepted best practice: using GCD. – Nicolas Miari Aug 10 '15 at 01:54
  • @NicolasMiari Yes, I get that. However, I didn't know about the singleton pattern in iOS until just now, when I asked this. – DDPWNAGE Aug 10 '15 at 01:55

1 Answers1

4

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

Cole
  • 2,641
  • 1
  • 16
  • 34
  • Thank you! The other answer provided a link and my question was marked as a duplicate because, apparently, asking that is the same as asking about whether or not GCD's `dispatch_once` is good for iOS 4.0. – DDPWNAGE Aug 10 '15 at 01:19