Correct Singleton Pattern Objective C (Ios)

Correct Singleton Pattern Objective C (iOS)?

Keep it simple:

+(instancetype)sharedInstance
{
static dispatch_once_t pred;
static id sharedInstance = nil;
dispatch_once(&pred, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}

- (void)dealloc
{
// implement -dealloc & remove abort() when refactoring for
// non-singleton use.
abort();
}

That is it. Overriding retain, release, retainCount and the rest is just hiding bugs and adding a bunch of lines of unnecessary code. Every line of code is a bug waiting to happen. In reality, if you are causing dealloc to be called on your shared instance, you have a very serious bug in your app. That bug should be fixed, not hidden.

This approach also lends itself to refactoring to support non-singleton usage modes. Pretty much every singleton that survives beyond a few releases will eventually be refactored into a non-singleton form. Some (like NSFileManager) continue to support a singleton mode while also supporting arbitrary instantiation.

Note that the above also "just works" in ARC.

What should my Objective-C singleton look like?

Another option is to use the +(void)initialize method. From the documentation:

The runtime sends initialize to each class in a program exactly one time just before the class, or any class that inherits from it, is sent its first message from within the program. (Thus the method may never be invoked if the class is not used.) The runtime sends the initialize message to classes in a thread-safe manner. Superclasses receive this message before their subclasses.

So you could do something akin to this:

static MySingleton *sharedSingleton;

+ (void)initialize
{
static BOOL initialized = NO;
if(!initialized)
{
initialized = YES;
sharedSingleton = [[MySingleton alloc] init];
}
}

What is the use of Singleton class in objective-c?

A singleton is a special kind of class where only one instance of the class exists for the current process. In the case of an iPhone app, the one instance is shared across the entire app.

Have a look at these tutorials :

http://pixeleap.com/?p=19

http://www.codeproject.com/Tips/232321/Implement-Objective-C-Singleton-Pattern

http://xcodenoobies.blogspot.in/2012/08/how-to-pass-data-between.html

http://www.johnwordsworth.com/2010/04/iphone-code-snippet-the-singleton-pattern/

http://www.idev101.com/code/Objective-C/singletons.html

And this video tutorial :

http://www.youtube.com/watch?v=FTfEN8KQPK8

How to create singleton class in objective C

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)
...

The use of singleton class in objective c and swift

To me it seems you do not need a singleton at all. I suggest you would be best of redesigning the architecture to have a user class that can store the information you are needing (and more if you finds the need in the future).

Then you could either pass that user object around between the view controllers as they need or perhaps easier define a currentUser property for the app delegate class.

That way each view controller can obtain the app delegate from the NSApp global reference to the application object and then get the current user object from there. With this pattern the app delegate acts as the globally accessible singleton you need without any need to manage it yourself.

Singleton with parameter iOS

There are a number of problem in this design:

  1. As recommended by Apple, should dispatch_once instead of @synchronized(self) for singleton:

    static MyClass *sharedInstance = nil;
    static dispatch_once_t onceToken = 0;
    dispatch_once(&onceToken, ^{
    sharedInstance = [[MyClass alloc] init];
    // Do any other initialisation stuff here
    });
    return sharedInstance;

    Refer to this question for more detail: Why does Apple recommend to use dispatch_once for implementing the singleton pattern under ARC?

  2. Bad API design to put singleton in alloc.

    As indicated by the name of the method alloc, it means that some memory will be allocated. However, in your case, it is not. This attempt to overwrite the alloc will cause confusion to other programmers in your team.

  3. Bad idea to use NSAssert in your -init.

    If you want to disable a method, disable it by putting this in your header file:

    - (id)init __attribute__((unavailable)); 

    In this case, you will get a compile error instead of crashing the app at run time.
    Refer to this post for more detail: Approach to overriding a Core Data property: isDeleted

    Moreover, you can even add unavailable message:

    - (id)init __attribute__((unavailable("You cannot init this class directly. It needs UserAccountDataSource as a parameter")));
  4. Sometime input parameters is ignored with no warning.

    In your following code, how would the programmer who is calling this function know that the input parameter userAccount is sometimes ignored if an instance of the class is already created by someone else?

    - (id)sharedInstanceWithAccount:(UserAccount *)userAccount {
    if (!sharedInstance) {
    @synchronized(self) {
    sharedInstance = [[[self class] alloc] initWithAccount:userAccount];
    }
    }
    return sharedInstance;
    }

In short, don't think it is a good idea to create singleton with parameter. Use conventional singleton design is much cleaner.

How do I implement an Objective-C singleton that is compatible with ARC?

In exactly the same way that you (should) have been doing it already:

+ (instancetype)sharedInstance
{
static MyClass *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[MyClass alloc] init];
// Do any other initialisation stuff here
});
return sharedInstance;
}

Singleton Object in iOS

You can forbid calls of init with such trick:
add - (instancetype)init NS_UNAVAILABLE; definition to your singleton interface.

Instead of [[PhotoManager alloc] init]; use [[[self class] alloc] init];

PhotoManager *sharedManager = [[PhotoManager alloc] init]; won't compile.

There is my example:

@interface SomeSingleton : NSObject

+ (instancetype)sharedInstance;
- (instancetype)init NS_UNAVAILABLE;

@end

@implementation SomeSingleton

+ (instancetype)sharedInstance {
static dispatch_once_t onceToken;
static SomeSingleton *instance;
dispatch_once(&onceToken, ^{
instance = [[[self class] alloc] init];
});

return instance;
}

- (instancetype)init {
self = [super init];

return self;
}

@end

As result SomeSingleton *s1 = [SomeSingleton sharedInstance]; works, but SomeSingleton *s2 = [[SomeSingleton alloc] init]; leads to the compile error.



Related Topics



Leave a reply



Submit