简体   繁体   中英

Objective-C singleton pattern in iOS 5+

I've been reading a lot of threads and blog articles about how to implement a singleton in objective-c, several of them maybe being a bit deprecated (year 2010 or earlier), and it seems like people have different opinions regarding this issue... Does Apple have documentation about implementing a singleton? I couldn't find it. If so, could somebody tell me where?

I need a singleton for a class that has some both public and private variables. Currently, this is the implementation I have for such class:

@interface MySingleton ()
   @property (strong, nonatomic) NSString *state;
@end

@implementation MySingleton

@synthesize state = _state;
@synthesize count = _count;

static MySingleton *sharedObject = nil;

+ (MySingleton *)sharedInstance
{
   static dispatch_once_t _singletonPredicate;

   dispatch_once(&_singletonPredicate, ^{
      sharedObject = [[super allocWithZone:nil] init];
   });

   return sharedObject;
}

+ (id)allocWithZone:(NSZone *)zone 
{
   return [self sharedInstance];
}

Should be this the recommended way? And how should I initialize the instance variables, public and private?

Another issue I'd like to make clear about singleton is: will this generate a memory leak? Is the use of singletons actually recommended in iOS?

Thanks

The above is correct, along with @miho's comment about includng the static object inside of the sharedInstance method. But there is no reason to override +allocWithZone: . Singletons in ObjC are generally "shared," not forced. You're free to create other instances of a "singleton." If it's illegal to create other instances, then you should make init perform an NSAssert rather than fooling the caller in +allocWithZone: . If your singleton is mutable (and most are), you absolutely should not override +allocWithZone: this way.

Another issue I'd like to make clear about singleton is: will this generate a memory leak?

No. This object will never be released, but it will always be accessible. That is not a leak.

Is the use of singletons actually recommended in iOS?

Yes, and it is a very common pattern, used all over the Cocoa frameworks. That said, there are various other patterns that have started to recently become somewhat popular among developers. Dependency Injection is getting some interest, though I don't see it in practice very often. Reducing your reliance on singletons can improve testability, and I have been experimenting recently with how to eliminate some of them in my code with some success. But they have a long, proud history in Cocoa, and I do not consider them a problem.

EDIT: you have one actual bug in your code. You should be calling [[self alloc] init] , not [[super alloc] init] . There's no reason to ever call +allocWithZone: , just use +alloc . (The time when ...WithZone: methods were useful has long passed.)

In Xcode, under 'Search Documentation' enter Creating a Singleton Instance . There are lots of results (but the link above, at the bottom of the page, has example code).

Yes, this is the recommended way. There is only one small difference of how I use it: I define the sharedObject as static variable inside the + (MySingleton *)sharedInstance method, because it shouldn't be possible to access the variable from anywhere else then from the getter method.

And no, you won't create a memory leak. When your app is terminated all reserved memory used by your app will be released anyway and there is no other situation where a static shared instance should get released. In pre-ARC area it even was common to override the release method do prevent accidentally releasing of the object.

A bit of warning using gcd for singletons:

dispatch_once(&_singletonPredicate, ^{
      sharedObject = [[super allocWithZone:nil] init];
   });

if the init method for some reason addresses the singleton object directly or indirectly, there will be a deadlock. For this reason I believe that the more appropriate way to write a singleton is through the

+ (void) initialize

method

I am still using the singleton header thingy from CocoaWithLove - may be a bit dated but still works like a charm. It basically does the same as described here referring to Apples documentation and I would assume at least Apple's documentation ( bottom of this page ) is still valid. There are people assuming it will stay valid indefinitely sine it is the official solution Apple suggested.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM