Objective-C的单例模式(singleton)

来源:互联网 发布:淘宝支付宝怎么解绑 编辑:程序博客网 时间:2024/05/21 19:29

如果你准备写一个类,希望保证只有一个实例存在,同时可以得到这个特定实例提供服务的入口,那么可以使用单态设计模式。

单态模式在Java、C++中很常用,在Cocoa里,也可以实现。

但是,

Objective-C的单例模式绝对和你所想象不一样,他的写法和你所见过的所有语言的写法都不一样。

 

官方建议

 

由于自己设计单态模式存在一定风险,主要是考虑到可能在多线程情况下会出现的问题,因此苹果官方建议使用以下方式来实现单态模式:

static MyGizmoClass *sharedGizmoManager = nil; 
+ (MyGizmoClass*)sharedManager 

    @synchronized(self) { 
        if (sharedGizmoManager == nil) { 
            [[self alloc] init]; // assignment not done here 
        } 
    } 
    return sharedGizmoManager; 

+ (id)allocWithZone:(NSZone *)zone 

    @synchronized(self) { 
        if (sharedGizmoManager == nil) { 
            sharedGizmoManager = [super allocWithZone:zone]; 
            return sharedGizmoManager;  // assignment and return on first allocation 
        } 
    } 
    return nil; //on subsequent allocation attempts return nil 

- (id)copyWithZone:(NSZone *)zone 

    return self; 

- (id)retain 

    return self; 

- (unsigned)retainCount 

    return UINT_MAX;  //denotes an object that cannot be released 

- (void)release 

    //do nothing 

- (id)autorelease 

    return self; 
}

 

开源模板(见附件下载)

程序员都是偷懒的,现在流行使用一个宏定义来搞定这许多的事,而且考虑的更加周全。

单例包含以下接口 

+ (MyClass*) sharedInstance; 
+ (void) purgeSharedInstance;

 

调用sharedInstance会创建并返回单例

调用purgeSharedInstance会销毁单例

手动调用alloc也可以保证是单例,你可以这样调用

[[MyClass alloc] initWithParam:firstParam secondParam:secondParam];

只是要保证在sharedInstance之前调用,因为只有一次创建机会。

下面是使用宏的写法“ 

MyClass.h: 
======================================== 
    #import "SynthesizeSingleton.h" 

    @interface MyClass: SomeSuperclass 
    { 
        ... 
    } 
    SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(MyClass); 

    @end 
======================================== 


    MyClass.m: 
======================================== 
    #import "MyClass.h" 

    @implementation MyClass 

    SYNTHESIZE_SINGLETON_FOR_CLASS(MyClass); 

    ... 

    @end 
========================================


上面介绍了创建单例的方式,不过后来发现其实在ios 4.0后有更加简单的方式。

就是使用GCD的功能

代码如下:

+ (instantClass *)sharedClient {

static instantClass *_sharedClient = nil;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

_sharedClient = [[instantClass allocinit];

});

return _sharedClient;

}


http://arthurchen.blog.51cto.com/2483760/642536

原创粉丝点击