开发设计模式——单例模式

我们常见的设计模式,大致可以分为以下三类:创建型、结构性、行为型。今天我们要说的单例模式,属于三种类型当中的创建型。


在开始之前呢,我们需要搞懂一个问题,就是我们为什么要用单例,它产生的背景是怎么样的呢?其实这与我们的开发习惯有很大关系。


在xcode 4.2之前我们一直是手动分配和释放内存,也就是MRC,每当我们要销毁实例,都要手动release去释放内存,但是这步操作我们经常会忘记,这个问题一直困扰着开发开发人员,即使是很注意了也不能完全避免。


xcode 4.2之后引入了ARC机制,系统可以自己去管理内存了,以前释放的工作,不再需要我们手动去操作,这给开发人员省了不少事。但ARC同时也存在一个问题,就是要销毁的对象,我们并不知道它是何时去释放,换句话说,对象并不会马上释放,这个操作会有一定延时。在创建对象较多,将被销毁的对象没有马上释放的情况下,系统的性能就会受到一定影响。


说到这里我想大家多少明白了,在ARC机制下,对象没有被马上释放,我们只有通过尽可能少的创建实例对象的方式,去减少性能上的消耗,同时,在程序的不同的地方,我们可能需要用到同一个对象,并且他的属性和接口都不会改变,为了避免创建多个重复的对象,单例模式诞生了。


设计模式不是某种语言的标准和规范,它之所以被设计出来,是因为经过大量的实践,人们产生了这样的需求,为了满足自己的需求,我们才设计出了各种各样的设计模式。


废话说的差不多了,接下来我们就来看看它有什么特点。


第一个特点:必须有且只有一个实例,它是全局唯一的

第二个特点:必须自行创建一个实例

第三个特点:必须提供一个全局接口,暴露给外部使用


具体的实现思路是怎么样的呢?


首先,要提供一个静态实例,一般情况下设置为nil,不仅是OC,在Swift、Java中也是如此,其次,要提供一个方法创建单例,如果单例存在就返回,如果不存在就创建,然后,在OC里面重写父类中的allocWithZone方法,保证是一个单例,当我们在调用alloc的时候会调用该方法,最后,根据实际情况,重写父类copyWithzone等等......

首先我们来实现一个非线程安全的单例:

static RCMailViewController *instance = nil;

+ (instancetype)sharedInstance {
    if (instance == nil) {
        instance = [[RCMailViewController alloc] init];
    }
    return instance;
}

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

在确定只有一个线程的时候,用这种不写法是没有问题的,但是现在绝大部分程序都是多线程,这种写法就有问题了。

多线程的时候,为了确保线程安全,我们一般这样写:

static RCMailViewController *instance = nil;

+ (instancetype)sharedInstance {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (instance == nil) {
	instance = [[RCMailViewController alloc] init];
        }
    });
    return instance;
}

+(id)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (instance == nil) {
            instance = [super allocWithZone:zone];
        }
    });
    return instance;
}

其实单里的实现方式还有很多,比如饿汉式,@synchronized等等,我这里就不再写了,最常用的就是用GCD线程安全的方式,并且allocWithZone方法通常可以不写。
以上这些希望会对你有帮助。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值