开发者

singleton class in objective-C

I want to have one object that is initialized in the delegate and I want to be able to use this object anywhere across view controllers (doesn't depend on what view I am currently at). I am guessing the solution to this would be to have a singleton class, so far I have the following:

@interface LocationManager : NSObject <CLLocationManagerDelegate>{
   开发者_运维技巧 NSDate *enter;
    NSDate *exit;
    CLLocationManager * manager;

}

@property (nonatomic, retain) NSDate * enter;
@property (nonatomic, retain) NSDate * exit;

- (BOOL)registerRegionWithLatitude:(double)latitude andLongitude:(double)longitude;
+ (LocationManager *)instance;

@end


#import "LocationManager.h"

@implementation LocationManager
@synthesize enter;
@synthesize exit;

#pragma mark - CLLocationManager delegate
static LocationManager *gInstance = NULL;


+ (LocationManager *)instance
{
    @synchronized(self)
    {
        if (gInstance == NULL)
            gInstance = [[self alloc] init];
    }
    return(gInstance);
}

@end

Is this correct? So all I need to do to access this is just to call instance? Inside LocationManager I also want to have only one CLLocationManager, called manager.. however, where do I initialize it so I only have one? Can I do the following? Most other singleton examples doesn't have any variables in the class, so that's where I got confused

+ (LocationManager *)sharedLocationManager
{
    @synchronized(self)
    {
        if (lm == NULL){
            lm = [[self alloc] init];
            lm.manager = [[CLLocationManager alloc] init];
            lm.manager.delegate = lm;
        }
    }
    return(lm);
}


Basically -- yes.
Just a couple of small things:
static LocationManager *gInstance = NULL;
instead of NULL, you should use nil, it's a convention in Objective-C.

You should also overwrite alloc, new, copyWithZone:, and mutableCopyWithZone:. From Buck/Yacktman: "Cocoa Design Patterns", p. 153:

+ (id)hiddenAlloc  
{
  return [super alloc];
}

+ (id)new
{
  return [self alloc];
}

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

- (id)copyWithZone:(NSZone *)zone
{
  [self retain];
  return self;
}

- (id)mutableCopyWithZone:(NSZone *)zone
{
  return [self copyWithZone:zone];
}

This way, your singleton object cannot be copied. You need to call hiddenAlloc from your instance method (by the way, the method to access a Singleton object is often called sharedInstance in Objective-C).


For other singleton styles with their pros and cons, check out this question.

Personally, I prefer this style (copied from one of the answers on that link):

static MySingleton *sharedSingleton;

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


In fact, there's a tried-and-true method to create singletons already. Download the SynthesizeSingleton.h file (from a Cocoa with Love article). It contains a massive amount of pre-processor code which will generate any singleton for you. Hit the article for more details.


Since the factory method "instance" is a class-level method, the @synchronized block should be @synchronized([LocationManager class]) { //}

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜