首页 > 学院 > 开发设计 > 正文

iOS-单例设计模式

2019-11-14 18:14:03
字体:
来源:转载
供稿:网友

单例应用场合

在iOS的生命周期内,有时候我们只需要某个类的一个实例。

例如UIapplication, UIAccelerometer, NSUserDefaults, NSNotificationCenter, NSFileManger, NSBundle这些都是单例类的典型代表。

如何创建单例类

  1. 创建一个静态对象
  2. 提供一个静态方法
  3. 重写alloc方法

代码演示

我们首先创建一个类Singleton, 继承自NSObject.

添加一个静态全局变量:

static Singleton *_singleton = nil;

 创建一个静态的方法:

+(Singleton *)shareSingleton{    //返回对象前需要判断,这个对象之前是否创建过,如果没有创建过,就需要创建一个对象,如果创建过,就把上一次的对象返回出去。这样可以保证创建的对象是唯一的对象    //@synchronized:多个线程同时访问单例类,就会创建多个单例类,我们需要加锁。    @synchronized(self)    {        if (_singleton == nil)        {            _singleton = [[self alloc]init];        }        return _singleton;    }}

 我们创建单例类的目的是在全局只能创建一个对象,但是如果我们使用上面的方法创建有一个问题,就是如果用户不使用shareSingleton创建对象,而是使用alloc方法创建对象,就会又生成一个对象实例,这跟我们项目中只生成一个冲突,那么我们怎么办呢?

第一反应,我们需要重写alloc方法,实际上我们没有必要重写alloc方法。(下文会详述)

我们先重写alloc方法:

+(id)alloc{     @synchronized(self)    {        if (_singleton == nil)        {            _singleton = [super alloc];        }        return _singleton;    }}

 既然用户可能用alloc方法创建对象,那么用户有没有可能使用allocWithZone创建对象呢?

我们在此又需要重写allocWithZone这个方法:

+(id)allocWithZone:(struct _NSZone *)zone{    @synchronized(self)    {        if (_singleton == nil)        {            _singleton = [super allocWithZone:zone];        }        return _singleton;    }}

 重写alloc,和重写allocWithZone有什么区别呢?

allocWithZone是一个比较全面的方法,在alloc方法内部,会调用allocWithZone这个方法。

使用allocWithZone不会调用alloc

所以没必要重写alloc,直接重写allocWithZone即可。

 基本的代码是:

#import "Singleton.h"static Singleton *_singleton = nil;@implementation Singleton+(Singleton *)shareSingleton{       @synchronized(self)    {        if (_singleton == nil)        {            _singleton = [[self alloc]init];        }        return _singleton;    }}+(id)allocWithZone:(struct _NSZone *)zone{    @synchronized(self)    {        if (_singleton == nil)        {            _singleton = [super allocWithZone:zone];        }        return _singleton;    }}

 上述的代码只是在ARC中可以正确使用,如果实在MRC中,有retain,copy,release, autorelease,这些方法都会使得引用计数变化,我们都需要对这些方法重写。

-(id)retain{    return _singleton;}-(void)release{    }-(id)autorelease{    return _singleton;}-(id)copy{    return _singleton;}-(NSUInteger)retainCount{    return 1;}

 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表