2011-03-25 72 views
0

我想要在委托中初始化一个对象,我希望能够在视图控制器的任何位置使用此对象(不依赖于我当前的视图)。我猜的解决方案,这将是有一个单独的类,到目前为止,我有以下几点:singleton class in objective-C

@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中我也想只有一个叫做manager的CLLocationManager ..但是,我在哪里初始化它,所以我只有一个?我可以做以下吗?大多数其他单例的例子没有任何类的变量,所以这就是我困惑的地方

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

谷歌搜索“目标c单”揭示了许多数千次点击。 – 2011-03-25 22:14:53

+0

我将其命名为'sharedLocationManager'而不是'instance'。 Apple以这种方式命名它们(除了'NSNull'和'NSUserDefaults',但这些都是特殊的)。 – 2011-03-25 22:16:08

回答

1

基本上 - 是的。
只是一对夫妇的小东西:
static LocationManager *gInstance = NULL;
而不是NULL,你应该使用nil,它是在Objective-C的约定。

您还应该覆盖alloc,new,copyWithZone:mutableCopyWithZone:。从巴克/亚克曼:“可可设计模式”,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]; 
} 

这样,您的单例对象不能被复制。您需要从instance方法中调用hiddenAlloc(顺便提一下,Objective-C中访问单例对象的方法通常被称为sharedInstance)。

+0

那个CLLocationManager呢? – aherlambang 2011-03-25 22:24:25

+1

夫妇的事情:因为'alloc'只是简单地调用'allocWithZone:',所以你不需要重写它们。 'allocWithZone:'应该简单地返回单例实例(当然保留),这样如果你尝试分配/初始化一个新实例,你只需要返回单例。 – 2011-03-25 22:25:24

+0

我感到困惑的一件事就是在这个单例类中有一个CLLocationManager实例.. – aherlambang 2011-03-25 22:31:31

0

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

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

static MySingleton *sharedSingleton; 

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

答案的唯一缺点是,这不会完全是“延迟加载”。因为即使调用了MySingleton的类方法,也会立即创建sharedInstance对象。 – rishabh 2013-02-03 07:35:52

+0

这是否是“下行”取决于您的需求。至少对于原始问题“延迟加载”没有被要求。 – 2013-02-04 11:46:01

0

由于工厂方法“实例”是一个类级的方法,所述@synchronized块应该是 @synchronized([的LocationManager类]){// }

+0

类方法中的'self'指的是类,因此至少在这方面,原始代码按照预期工作。 – zoul 2012-06-04 18:27:42

+1

您的代码中已经有一个单例类AppDelegate类。 你应该最好避免创建一个单例,除非明确要求。 也许,在你的情况下,位置管理器代码可以简单地设置在AppDelegat中,并将坐标设置为AppDelegate类中的属性。 – rishabh 2012-09-08 13:27:40