Cocoa的单例(singleton)设计模式

原帖地址:http://www.cocoachina.com/newbie/basic/2009/0611/254.html


1、普通方法

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

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

  1. 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;
    }

    2、使用GCD创建单例

    创建一个新类,命名它为LibraryAPI,设置父类为NSObject.打开LibraryAPI.h,用如下代码替换它的内容
    @interfaceLibraryAPI : NSObject   
        
    + (LibraryAPI*)sharedInstance;   
        
    @end

    现在打开LibraryAPI.m,在@implementation 那一行后面插入下面的方法:
    + (LibraryAPI*)sharedInstance   
    {   
        // 1   
        static LibraryAPI *_sharedInstance = nil;   
        
        // 2   
        static dispatch_once_t oncePredicate;   
        
        // 3   
        dispatch_once(&oncePredicate, ^{   
            _sharedInstance = [[LibraryAPI alloc] init];   
        });   
        return _sharedInstance;   
    }   

    在这个简短的方法中,有一些需要需要注意的点:
    1.声明一个静态变量去保存类的实例,确保它在类中的全局可用性。
    2.声明一个静态变量dispatch_once_t ,它确保初始化器代码只执行一次
    3.使用Grand Central Dispatch(GCD)执行初始化LibraryAPI变量的block.这  正是单例模式的关键:一旦类已经被初始化,初始化器永远不会再被调用。
     
    下一次你调用sharedInstance的时候,dispatch_once块中的代码将不会执行(因为它已经被执行了一次),你将得到原先已经初始化好的实例。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值