您的位置:首页 > 移动开发 > IOS开发

iOS 实用方法创建单利+宏定义创建单利

2016-09-11 13:40 155 查看
有两种方法来创建单例,下面分别介绍


1、GCD方式创建单例


2、互斥锁方式

上面两种方式都可以创建单例,而且保证了用户不管是通过shareInstance方法,还是alloc、copy方法得到的实例都是一样的。

上面代码的关键之处就在于如何在多线程情况下保证创建的单例还是同一个。

我们先看看在GCD情况下,如果不使用dispatch_once和同步锁创建单例会出现什么问题,去掉两者后创建单例的代码如下

假设此时有两条线程:线程1和线程2,都在调用shareInstance方法来创建单例,那么线程1运行到
if (_instance == nil)
出发现_instance = nil,那么就会初始化一个_instance,假设此时线程2也运行到if的判断处了,此时线程1还没有创建完成实例_instance,所以此时_instance = nil还是成立的,那么线程2又会创建一个_instace。

此时就创建了两个实例对象,导致问题。


解决办法1、使用dispatch_once

dispatch_once保证程序在运行过程中只会被运行一次,那么假设此时线程1先执行shareInstance方法,创建了一个实例对象,线程2就不会再去执行dispatch_once的代码了。从而保证了只会创建一个实例对象。


解决办法2、使用互斥锁

假设此时线程1在执行shareInstance方法,那么synchronize大括号内创建单例的代码,如下所示:

就会被当做一个任务被加上了一把锁。此时假设线程2也想执行shareInstance方法创建单例,但是看到了线程1加的互斥锁,就会进入睡眠模式。等到线程1执行完毕,才会被唤醒,然后去执行上面所示的创建单例的代码,但是此时_instance !=nil,所以不会再创建新的实例对象了。从而保证只会创建一个实例对象。

但是互斥锁会影响性能,所以最好还是使用GCD方式创建单例。


宏创建单例

如果我们需要在程序中创建多个单例,那么需要在每个类中都写上一次上述代码,非常繁琐。

我们可以使用宏来封装单例的创建,这样任何类需要创建单例,只需要一行代码就搞定了。


实现代码


如何调用

假设我们要在类viewcontroller中使用,调用方法如下:


输出结果

可以看到四个对象的内存地址完全一样,说明是同一个对象
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: