iOS 创建单例的两种方法
创建一个单例很多办法。我先列举一个苹果官方文档中的写法。
- static AccountManager *DefaultManager = nil;
- + (AccountManager *)defaultManager {
- if (!DefaultManager) DefaultManager = [[self allocWithZone:NULL] init];
- return DefaultManager;
- }
当然,在iOS4之后有了另外一种写法:
- + (AccountManager *)sharedManager
- {
- static AccountManager *sharedAccountManagerInstance = nil;
- static dispatch_once_t predicate;
- dispatch_once(&predicate, ^{
- sharedAccountManagerInstance = [[self alloc] init];
- });
- return sharedAccountManagerInstance;
- }
该写法来自 objcolumnist,文中提到,该写法具有以下几个特性:
1. 线程安全。
2. 满足静态分析器的要求。
3. 兼容了ARC
然后我还有点好奇的是dispatch_once,这个函数,没见过啊。
于是就到官方的文档里找找看,是怎么说的。
下面是官方文档介绍:
dispatch_once
Executes a block object once and only once for the lifetime of an application.
void dispatch_once(
dispatch_once_t *predicate,
dispatch_block_t block);
Parameters
predicate
A pointer to a dispatch_once_t structure that is used to test whether the block has completed or not.
block
The block object to execute once.
Discussion
This function is useful for initialization of global data (singletons) in an application. Always call this function before using or testing any variables that are initialized by the block.
If called simultaneously from multiple threads, this function waits synchronously until the block has completed.
The predicate must point to a variable stored in global or static scope. The result of using a predicate with automatic or dynamic storage is undefined.
Availability
- Available in iOS 4.0 and later.
Declared In
dispatch/once.h
我们看到,该方法的作用就是执行且在整个程序的声明周期中,仅执行一次某一个block对象。简直就是为单例而生的嘛。而且,有些我们需要在程序开头初始化的动作,如果为了保证其,仅执行一次,也可以放到这个dispatch_once来执行。
然后我们看到它需要一个断言来确定这个代码块是否执行,这个断言的指针要保存起来,相对于第一种方法而言,还需要多保存一个指针。
方法简介中就说的很清楚了:对于在应用中创建一个初始化一个全局的数据对象(单例模式),这个函数很有用。
如果同时在多线程中调用它,这个函数将等待同步等待,直至该block调用结束。
这个断言的指针必须要全局化的保存,或者放在静态区内。使用存放在自动分配区域或者动态区域的断言,dispatch_once执行的结果是不可预知的。
总结:1.这个方法可以在创建单例或者某些初始化动作时使用,以保证其唯一性。2.该方法是线程安全的,所以请放心大胆的在子线程中使用。(前提是你的dispatch_once_t *predicate对象必须是全局或者静态对象。这一点很重要,如果不能保证这一点,也就不能保证该方法只会被执行一次。)
转:http://blog.sina.com.cn/s/blog_69081e0601019m1z.html
iOS 创建单例的两种方法的更多相关文章
- IOS创建单例的两种方法
1.0 苹果官方写法: static AccountManager *DefaultManager = nil; + (AccountManager *)defaultManager { if ( ...
- 【iOS开发】创建单例的两种方法
创建一个单例很多办法.我先列举一个苹果官方文档中的写法. [cpp] view plaincopy static AccountManager *DefaultManager = nil; + ( ...
- iOS单例的两种实现
单例模式算是开发中比较常见的一种模式了.在iOS中,单例有两种实现方式(至少我目前只发现两种).根据线程安全的实现来区分,一种是使用@synchronized,另一种是使用GCD的dispatch_o ...
- objc单例的两种安全实现方案
所有转出博客园,请您注明出处:http://www.cnblogs.com/xiaobajiu/p/4122034.html objc的单例的两种安全实现方案 首先应该知道单例的实现有两大类,一个是懒 ...
- .net中创建xml文件的两种方法
.net中创建xml文件的两种方法 方法1:根据xml结构一步一步构建xml文档,保存文件(动态方式) 方法2:直接加载xml结构,保存文件(固定方式) 方法1:动态创建xml文档 根据传递的值,构建 ...
- 使用express创建node服务器的两种方法及区别
使用express创建node服务器有两种方法,如下所示: 方法一: var express = require('express'); var app = express(); app.listen ...
- iOS:创建单例对象的两种方式
单例模式:创建单例对象的两种方式 方式一:iOS4版本之前 static SingleClassManager *singleManager = nil; +(SingleClas ...
- js阻止表单提交的两种方法
下面直接看代码. <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- AutoCAD.NET二次开发:创建自定义菜单的两种方法比较
目前我已经掌握的创建CAD菜单方法有两种: COM方式: http://www.cnblogs.com/bomb12138/p/3607929.html CUI方式: http://www.cnblo ...
随机推荐
- jmeter --使用put方法上传文件
今天来记录下put上传文件遇到的坑吧!折腾死我了, 刚开始的时候用的jmeter3.0,各种尝试,发现始终告诉我文件内容为空<actual file content,not shown here ...
- Windows下安装Python及Eclipse中配置PyDev插件
最近开始接触Python,鉴于之前安装Java的教训,决定这次边安装Python,边写下历程,供日后反复使用. 在Python官网http://www.python.org/下载Python版本,鉴于 ...
- 深入理解java虚拟机-00
这本书买了有两年了,只有买回来翻了两页...今天电脑有点卡,游戏玩不了了,就来看看这本书. 首先看了序言,这本书是第二版,讲解的jdk版本是1.7,现在公司用的1.8,而且1.8的改动也挺大的,不过在 ...
- 数组中累加和小于等于k的最长子数组
问题描述: 给定一个无序数组arr,其中元素可正.可负.可0,给定一个整数 k.求arr所有的子数组中累加和小于或等于k的最长子数组长度.例如:arr=[3,-2,-4,0,6],k=-2,相加和小于 ...
- Ruby语言学习笔记
在codecademy上开始玩ruby了 1.数据类型:boolean,string,number 变量直接用即可,不用声明(“拿来主义”) 运算符:+ - * / ** % == != && ...
- CI框架+Umeditor上传图片配置信息
Umeditor提供了一个上传文件通用的类Uploader.class.php, 首先将Uploader.class.php类放入CI框架的libraries目录下更名为Myuploader.php然 ...
- Using MongoDB in C#
In order to use MongoDB in C#, you can import MongoDB C# Driver to your project. It's best to create ...
- 德卡Z90读卡器读取社保卡,德卡Z90读卡器CSharp示例程序源码
前言,最近学习调用 医保卡业务,使用德卡读卡器,主要就是调用一个DLL,动态库文件. 借着自学的机会把心得体会都记录下来,方便感兴趣的小伙伴学习与讨论. 内容均系原创,欢迎大家转载分享,但转载的同时别 ...
- vue打包以及在Apache环境下的配置
vue打包,我们都清楚,实在记不住命令的可以去package.json中看: npm run build 打包后会生成dist文件夹,将dist文件夹下的所有文件复制到Apache下的www的文件夹下 ...
- Codeforces-1084C
title: Codeforces-1084C date: 2018-12-13 16:02:04 tags: acm 刷题 categories: Codeforces 概述 好久没写博客了,,,最 ...