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]) { //}
精彩评论