iOS 实用方法创建单利+宏定义创建单利
2016-09-11 13:40
155 查看
有两种方法来创建单例,下面分别介绍
上面两种方式都可以创建单例,而且保证了用户不管是通过shareInstance方法,还是alloc、copy方法得到的实例都是一样的。
上面代码的关键之处就在于如何在多线程情况下保证创建的单例还是同一个。
我们先看看在GCD情况下,如果不使用dispatch_once和同步锁创建单例会出现什么问题,去掉两者后创建单例的代码如下
假设此时有两条线程:线程1和线程2,都在调用shareInstance方法来创建单例,那么线程1运行到
此时就创建了两个实例对象,导致问题。
dispatch_once保证程序在运行过程中只会被运行一次,那么假设此时线程1先执行shareInstance方法,创建了一个实例对象,线程2就不会再去执行dispatch_once的代码了。从而保证了只会创建一个实例对象。
假设此时线程1在执行shareInstance方法,那么synchronize大括号内创建单例的代码,如下所示:
就会被当做一个任务被加上了一把锁。此时假设线程2也想执行shareInstance方法创建单例,但是看到了线程1加的互斥锁,就会进入睡眠模式。等到线程1执行完毕,才会被唤醒,然后去执行上面所示的创建单例的代码,但是此时_instance !=nil,所以不会再创建新的实例对象了。从而保证只会创建一个实例对象。
但是互斥锁会影响性能,所以最好还是使用GCD方式创建单例。
如果我们需要在程序中创建多个单例,那么需要在每个类中都写上一次上述代码,非常繁琐。
我们可以使用宏来封装单例的创建,这样任何类需要创建单例,只需要一行代码就搞定了。
假设我们要在类viewcontroller中使用,调用方法如下:
可以看到四个对象的内存地址完全一样,说明是同一个对象
1、GCD方式创建单例
2、互斥锁方式
上面代码的关键之处就在于如何在多线程情况下保证创建的单例还是同一个。
我们先看看在GCD情况下,如果不使用dispatch_once和同步锁创建单例会出现什么问题,去掉两者后创建单例的代码如下
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大括号内创建单例的代码,如下所示:但是互斥锁会影响性能,所以最好还是使用GCD方式创建单例。
宏创建单例
如果我们需要在程序中创建多个单例,那么需要在每个类中都写上一次上述代码,非常繁琐。我们可以使用宏来封装单例的创建,这样任何类需要创建单例,只需要一行代码就搞定了。
实现代码
如何调用
假设我们要在类viewcontroller中使用,调用方法如下:
输出结果
相关文章推荐
- iOS 创建使用静态库的方法
- [ios] xcode 4.2 创建 adhoc 发布应用测试方法
- iOS 导航控制器、标签、表视图的创建方法
- [iOS]单例的创建方法
- ios开发中,比较实用的全局宏定义分享
- PHP 5.0创建图形的实用方法完整篇第1/3页
- iOS--创建圆角图片的又一方法
- iOS 创建单例的两种方法
- iOS Dev (19) 在Xcode中创建iOS动态库的方法
- IOS开发笔记:xcode4.2下xib的创建和UI连接的实现方法
- ios 下创建、删除文件夹的方法
- ios开发创建单例的两种方法
- iOS中为UIColor创建类别 其中添加了几个常用的方法
- ios开发者创建app应用开发授权文件 实战方法:
- IOS中使用CATransition创建动画方法
- ios 下创建,删除文件夹的方法
- ios开发中,比较实用的全局宏定义分享
- win7下创建和删除服务的简单实用方法
- iOS中使用@方法快速创建对象
- 关闭ios虚拟键盘的几种实用方法