目标C中的单例类

时间:2011-03-25 22:05:51

标签: iphone objective-c design-patterns

我希望在委托中初始化一个对象,并希望能够在视图控制器的任何位置使用此对象(不依赖于我当前所处的视图)。我猜这个解决方案就是拥有一个单例类,到目前为止我有以下内容:

@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

这是对的吗?所以我需要做的就是调用实例?在LocationManager中我也想只有一个CLLocationManager,叫做manager ..但是,我在哪里初始化它所以我只有一个?我可以这样做吗?大多数其他单例示例在类中没有任何变量,所以这就是我困惑的地方

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

4 个答案:

答案 0 :(得分:1)

基本上 - 是的。
只是几件小事:
static LocationManager *gInstance = NULL;
而不是NULL,你应该使用nil,这是Objective-C中的约定。

您还应该覆盖allocnewcopyWithZone:mutableCopyWithZone:。来自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];
}

这样,您的单例对象无法复制。您需要从hiddenAlloc方法调用instance(顺便说一句,访问Singleton对象的方法通常在Objective-C中称为sharedInstance

答案 1 :(得分:0)

对于其他单身风格的优缺点,请查看this question

就个人而言,我更喜欢这种风格(从该链接上的一个答案中复制):

static MySingleton *sharedSingleton;

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

答案 2 :(得分:0)

事实上,已经有一种经过验证的方法来创建单身人士。下载SynthesizeSingleton.h文件(来自Cocoa with Love article)。它包含大量的预处理器代码,可以为您生成任何单例。点击文章了解更多详情。

答案 3 :(得分:0)

由于工厂方法“instance”是类级方法,因此@synchronized块应该是 @synchronized([LocationManager class]){ //}