iOS单例模式
来源:互联网 发布:知乎稿费 编辑:程序博客网 时间:2024/05/16 01:05
最近在iOS开发中,需要用到单例模式,于是自己动手写了一个,它看起来是这样的:
后来发现许多书上的做法都使用到了BOOL变量作为标值位,它看起来是这样的:
但是参考了苹果官方的单例模式代码,发现它看起来是这样的:
那么它们究竟有多大区别呢?
<1>
- + (id)sharedInstance
- {
- static id sharedInstance = nil;
- if (!sharedInstance) {
- sharedInstance = [[NSObject alloc] init];
- }
- return sharedInstance;
- }
后来发现许多书上的做法都使用到了BOOL变量作为标值位,它看起来是这样的:
<2>
- + (id)sharedInstance
- {
- static id sharedInstance = nil;
- static BOOL token = NO;
- if (!token) {
- token = YES;
- sharedInstance = [[NSObject alloc] init];
- }
- return sharedInstance;
- }
但是参考了苹果官方的单例模式代码,发现它看起来是这样的:
<3>
- + (id)sharedInstance
- {
- static id sharedInstance;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- sharedInstance = [[NSObject alloc] init];
- });
- return sharedInstance;
- }
那么它们究竟有多大区别呢?
原来,它们的区别在于多线程并发时的表现。
<1>使用了一个指针变量作为标志位,这在多线程并发时是不可取的,因为sharedInstance = [[NSObject alloc] init];这行代码的执行本身是需要时间的。很可能有两个线程同时进入到了这行代码,而这将导致内存泄漏。
<2>使用的标志位是一个BOOL变量,尽管token = YES;这行代码的执行也需要时间,但是它远远好过<1>
<3>使用了dispatch_once函数。这个函数来自于Grand Central Dispatch (GCD),Apple自Mac OS 10.6 / iOS 4.0引用了它。
该函数接收一个dispatch_once_t用于检查该代码块是否已经被调度的谓词(是一个长整型,实际上作为BOOL使用)。它还接收一个希望在应用的生命周期内仅被调度一次的代码块。这不仅意味着代码仅会被运行一次,而且还是线程安全的,你不需要使用诸如@synchronized之类的来防止使用多个线程或者队列时不同步的问题。
Apple的GCD Documentation证实了这一点:
如果被多个线程调用,该函数会同步等等直至代码块完成。
0 0
- iOS单例模式
- iOS 单例模式
- IOS 单例模式
- iOS 单例模式
- IOS单例模式
- ios单例模式
- iOS 单例模式
- iOS 单例模式
- IOS单例模式
- iOS 单例模式
- iOS 单例模式
- IOS 单例模式
- IOS---单例模式
- iOS--单例模式
- iOS 单例模式
- ios 单例模式
- iOS 单例模式
- IOS单例模式
- oracle_date
- The Log: What every software engineer should know about real-time data's unifying abstraction
- C++之枚举
- SDL2.0_07_classes
- windows平台下检测电池实现自动关机
- iOS单例模式
- java之UDP(datagramsocket,datagramPacket)实例
- 【干货】国外程序员整理的 C++ 资源大全
- Activity.startActivity()分析:本地进程部分
- use dynamic sql to output the result
- 金山WPS笔试题
- Java创建线程的两个方法
- DWR 报错:Error: java.lang.SecurityException, Session Error 和 Allocate exception for servlet 问题的解决办法
- ie6中的透明图片的解决办法