IOS设计模式之单例模式(Singleton)

定义

  保证一个类仅有一个实例,并提供一个该实例的全局访问点。

  定义包含三层含义:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须向整个系统提供这个实例。

结构图


从结构图可以看到,单例模式(Singleton)是比较独立的一个设计模式,它的主要特点是控制某个类的实例唯一性,通过上图我们知道它包含的类只有一个,就是Singleton。该模式中包含一个静态私有成员变量mySingleton与类方法sharedInstance()。sharedInstance ()方法负责实例化自己,然后存储在静态成员mySingleton变量中,以确保只有一个实例被创建。

单例模式的实现

  在Objective-C中实现单例模式,需要完成如下四个步骤:

  • 第一步:定义一个静态实例变量mySingleton(名字可以自己取),初始化为nil,代码如下所示:
1 static MySingleton *mySingleton = nil;
  • 第二步:实现一个类方法检查上面声明的静态实例是否为nil,如果是则新建并返回一个本类的实例,代码如下所示:

+ (id)sharedInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if(mySingleton == nil)
        {
            mySingleton = [[self alloc] init];
        }
    });
    return mySingleton;
}

【说明】:dispatch_once函数是GCD中的API,它保证应用程序即使在多线程环境下,也只执行一次。当然,也可以使用@synchronize来达到线程安全的目的,代码如下所示:

+ (id)sharedInstance
{
    @synchronized (self)
    {
        if (mySingleton == nil)
        {
            mySingleton = [[self alloc] init];
        }
    }
    return mySingleton;
}
  • 第三步:重写allocWithZone方法,用来保证使用alloc和init试图获得一个新实例的时候不产生新实例,代码如下所示:
+ (id)allocWithZone:(NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (mySingleton == nil)
        {
            mySingleton = [super allocWithZone:zone];
            NSLog(@"allocWithZone");
        }
    });
    return mySingleton; 
}
  • 第四步:适当实现copyWithZone,release和autorelease等方法。代码如下所示:
// 如果有其他初始化操作,可在这里进行初始化
- (id)init
{
    self = [super init];
    if (self != nil)
    {
        // 其他初始化操作
    }
    return self;
}

// 防止外界拷贝造成多个实例,保证实例的唯一性。
- (id)copyWithZone:(NSZone *)zone
{
    return self;
}

// 因为只有一个实例对象,所以retain不能增加引用计数。
- (id)retain
{
    return self;
}

// 因为只有一个实例对象,设置默认引用计数。这里是取的NSUinteger的最大值,当然也可以设置成1或其他值。
- (NSUInteger)retainCount
{
    return UINT_MAX;  // denotes an object that cannot be released
}

// oneway是用于多线程编程中,表示单向执行,不能“回滚”,即原子操作。该方法是空的,不让用户release掉这个对象。
- (oneway void)release
{
    //do nothing
}

//除了返回单例外,什么也不做。
- (id)autorelease
{
    return self;
}

// 该方法永远不会被调用,因为在程序的生命周期内容,该单例一直都存在。(所以该方法可以不实现)
- (void)dealloc
{
    [super dealloc];
}

【说明】:对于步骤二和步骤三,也可以按如下方式实现:

+ (id)sharedInstance
{
    @synchronized(self)
    {
        if(mySingleton == nil)
        {
            mySingleton = [[super allocWithZone:NULL] init];
            NSLog(@"allocWithZone");
        }
    }
    return mySingleton;
}

// 通过返回当前的sharedInstance实例,就能防止实例化一个新的对象。
+ (id)allocWithZone:(NSZone *)zone
{
    return [[self sharedInstance] retain];
}

单例模式在IOS中的应用

  单例模式在IOS中的应用非常广泛,如[NSNotificationCenter defaultCenter]、[UIApplication sharedApplication]、[NSFileManager defaultManager]等。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值