(一二三)基于GCD的dispatch_once实现单例设计
要实现单例,关键是要保证类的alloc和init只被调用一次,并且被自身强引用防止释放。
近日读唐巧先生的《iOS开发进阶》,受益匪浅,通过GCD实现单例就是收获之一,下面把这个方法与大家分享。
在GCD中,有一个函数dispatch_once,可以实现代码段的一次性执行,和static修饰的变量赋值的一次性一样,我们结合static和dispatch_once,就可以简单的实现单例。
下面的代码实现了SomeClass单例:
#import <Foundation/Foundation.h> @interface SomeClass : NSObject + (SomeClass *)sharedInstance; @end
#import "SomeClass.h"
@implementation SomeClass
+ (SomeClass *)sharedInstance{
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
@end
下面解释一下这段代码。
第一句新建一个sharedInstance静态强指针,是为了指向创建好的单例,防止其释放,只有第一次进入的时候指针被赋值为nil。
一定注意dispatch_once_t变量必须是静态,它的值用于判断是否已经执行一次。
第二句和dispatch_once是固定用法,这样可以实现block内的代码一次性执行,也就是说只有第一次调用这个方法时才会实例化类,之后都是返回指针指向的值。
最后返回指针,就相当于拿到了单例。
对单例的运行结果进行验证:
我们多次获取单例对象并且打印地址,可以发现地址是一样的。
#import "ViewController.h"
#import "SomeClass.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; SomeClass *sc1 = [SomeClass sharedInstance];
SomeClass *sc2 = [SomeClass sharedInstance];
SomeClass *sc3 = [SomeClass sharedInstance];
NSLog(@"%p %p %p",sc1,sc2,sc3); } @end
2015-08-17 20:59:22.139 基于GCD实现单例[2785:31918] 0x7fb40af11b90 0x7fb40af11b90 0x7fb40af11b90
通过这种方式,简单高效的实现了单例,值得使用。
(一二三)基于GCD的dispatch_once实现单例设计的更多相关文章
- 使用GCD的dispatch_once创建单例
使用GCD的dispatch_once创建单例 介绍了创建单例的方式,不过后来发现其实在ios 4.0后有更加简单的方式. 就是使用GCD的功能 代码如下: + (instantClass *)sha ...
- IOS:利用dispatch_once创建单例
在之前有一篇学习笔记中,记载了一篇如何在OC中实现单例的文章:<IOS学习笔记4—Objective C—创建单例>自苹果引入了Grand Central Dispatch (GCD)(M ...
- IOS基础学习日志(七)利用dispatch_once创建单例及使用
自苹果引入了Grand Central Dispatch (GCD)(Mac OS 10.6和iOS4.0)后,创建单例又有了新的方法,那就是使用dispatch_once函数,当然,随着演进的进行. ...
- ios oc 和 swfit 用dispatch_once 创建单例
网上已经有方法了,我这里就是抄了下,原文链接 http://bj007.blog.51cto.com/1701577/649413 http://blog.csdn.net/u010124617/ar ...
- ios--->使用@synchronized和dispatch_once实现单例
使用dispatch_once实现单例 单例实现的两种模式 @implementation XXClass //@synchronized来实现 + (id)sharedInstance { stat ...
- php : 单例设计演示
单例 : 保证只有一个实例 <?php /* * 单例设计 */ // 单例: 只能"创造"出它的一个对象实例 class Single{ // 第一步: 私有化构造方法 p ...
- Spring容器-ApplicationContext的单例设计
Spring容器-ApplicationContext的单例设计 每次通过new创建一个ApplicationContext容器,都会执行refresh方法,看源代码了解到这个refresh方法会 ...
- Swift中简单的单例设计
import Foundation class Test: NSObject { // 提供单例实例 static let shareInstance = Test() // 私有化构造方法 over ...
- JAVA设计模式:单例设计
1.单例设计Singleton的引出 单例设计,从名字上首先可以看出单---即只有一个,例---只的是实例化对象:那么单例也就是说一个类,只产生了一个实例化对象.但是我们都知道,一个类要产生实例化对象 ...
随机推荐
- hdu 5441 (并查集)
题意:给你n个点,m条边构成无向图.q个询问,每次一个值,求有多少条路,路中的边权都小于这个值 a->b 和 b->a算两种 思路:把权值从小到大排序,询问从小到大排序,如果相连则用并查集 ...
- Android毕业设计-微圈
勤拂拭软件出品,必属精品 : 勤拂拭软件 去年做了一个类似于我的朋友圈的项目,主要功能就是用户可以实时发表自己的动态,好友可以评论点赞什么的,可以建群,聊天啊,拉黑啊,反正是一个不错的社交软件,包含服 ...
- java continue与break区别
在循环体中跳出循环语句有continue与break语句 continue:跳出本次循环,包括本次循环continue后面的语句, break:跳出循环体,就是说一遇到break循环就结束. 代码: ...
- C# 枚举在项目中使用心得
阅读目录 基本介绍 使用注意 使用方法 扩展用法 本文主要是我在项目中对C#枚举的使用心得,如有不足的地方欢迎您指出. 一.基本介绍 枚举是由一组特定常量构成的一组数据结构,是值类型的一种特 ...
- Linux学习之CentOS(四)----Linux文件属性、所有者、群组、其他组及文件权限操作简要总结
Linux文件属性.所有者.群组.其他组及文件权限操作简要总结 首先介绍一个重要的知识点:文件属性控制权限 [root@www ~]# ls -al total 156 drwxr-x--- 4 ro ...
- JavaScript中的类
JavaScript类的相关知识 1.例子 /* 例1 */// 定义一个构造函数function Range(from, to){ this.from = from; this.to = ...
- ACM Ignatius and the Princess II
Problem Description Now our hero finds the door to the BEelzebub feng5166. He opens the door and fin ...
- Node.js DNS 模块
Node.js DNS 模块用于解析域名.引入 DNS 模块语法格式如下: var dns = require("dns") 方法 序号 方法 & 描述 1 dns.loo ...
- Bootstrap3 表格-基本表格
为任意 <table> 标签添加 .table 类可以为其赋予基本的样式 - 少量的内补(padding)和水平方向的分隔线.这种方式看起来很多余!?但是我们觉得,表格元素使用的很广泛,如 ...
- SQL Server 虚拟化(2)——理想的SQL Server虚拟机架构
本文属于SQL Server虚拟化系列 搭建SQL Server虚拟机,在各个组织之间都有自己的标准和最佳实践.从第一眼看去,光物理配置就有过百种,所有的这些细微差别都有可能为后续日常管理过程中故障侦 ...