原帖地址:http://www.galloway.me.uk/tutorials/singleton-classes/

本文为博主自行翻译,转载请注明出处:http://blog.csdn.net/iosevanhuang/article/details/13278323

“单例模式”是我在iOS中最常使用的设计模式之一。单例模式不需要传递任何参数,就有效地解决了不同代码间的数据共享问题。

背景

单例类是一个非常重要的概念,因为它们表现出了一种十分有用的设计模式。单例类的应用贯穿于整个iPhone SDK中。例如,UIApplication类有一个方法叫sharedApplication,从任何地方调用这个方法,都将返回与当前正在运行的应用程序相关联的UIApplication实例。

博主补充:单例类保证了应用程序的生命周期中有且仅有一个该类的实例对象,而且易于外界访问。

实现

你可以用以下代码实现一个Objective-C的单例类(ARC模式下,非ARC模式下面会讲到):

1
2
3
4
5
6
7
8
9
10
11
#import <foundation/Foundation.h>
 
@interface MyManager : NSObject {
NSString *someProperty;
}
 
@property (nonatomic, retain) NSString *someProperty;
 
+ (id)sharedManager;
 
@end
来自CODE的代码片
MyManager.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#import "MyManager.h"
 
@implementation MyManager
 
@synthesize someProperty;
 
#pragma mark Singleton Methods
 
+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
 
- (id)init {
if (self = [super init]) {
someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
}
return self;
}
 
- (void)dealloc {
// 永远不要调用这个方法
}
 
@end
来自CODE的代码片
MyManager.m

在这里我们定义了一个静态变量sharedMyManager,然后仅初始化一次该变量。这里使用了dispatch_once以保证该变量只被GCD初始化一次。操作系统将保证这是线程安全的。

如果不使用GCD,你可以使用以下代码:

1
2
3
4
5
6
7
8
+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
@synchronized(self) {
if (sharedMyManager == nil)
sharedMyManager = [[self alloc] init];
}
return sharedMyManager;
}
来自CODE的代码片
Non-GCD-based-code.m
 
接下来,当你需要使用这个单例对象时,你只要这样调用就可以了:
1
MyManager *sharedManager = [MyManager sharedManager];
来自CODE的代码片
snippet_file_0.m
我在我的代码中广泛使用单例类,比如创建一个单例类来处理CoreLocation或CoreData功能。
 
非ARC代码
虽然我并不那么推荐,但是如果你要使用非ARC环境的话,你应该使用以下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#import "MyManager.h"
 
static MyManager *sharedMyManager = nil;
 
@implementation MyManager
 
@synthesize someProperty;
 
#pragma mark Singleton Methods
+ (id)sharedManager {
@synchronized(self) {
if(sharedMyManager == nil)
sharedMyManager = [[super allocWithZone:NULL] init];
}
return sharedMyManager;
}
+ (id)allocWithZone:(NSZone *)zone {
return [[self sharedManager] retain];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)retain {
return self;
}
- (unsigned)retainCount {
return UINT_MAX; // 表示该对象永远不应被释放
}
- (oneway void)release {
// 从不释放
}
- (id)autorelease {
return self;
}
- (id)init {
if (self = [super init]) {
someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
}
return self;
}
- (void)dealloc {
// 从不调用该方法
[someProperty release];
[super dealloc];
}
 
@end
来自CODE的代码片
MyManager-non-ARC.m
博主:这里的单例都是懒汉式单例,当单例对象的获取方法第一次被调用时创建单例对象。而在类被加载时就创建单例对象叫做饿汉式单例。

ios之单例模式的更多相关文章

  1. iOS开发--单例模式

    单例模式在iOS开发中可能算是最常用的模式之一了,但是由于oc本身的语言特性,想要写一个正确的单例模式相对来说比较麻烦,这里我就抛砖引玉来聊一聊iOS中单例模式的设计思路.关于单例模式更多的介绍请参考 ...

  2. QF——iOS的单例模式

    iOS的单例模式: 单例,即为单个实例,确保一个类里只有一个实例,向整个系统提供一个唯一的实例. 甚至为了严格提供唯一的实例,通常只允许该类自己提供实例化的方法,不允许出现其他入口.这时我们通常得重写 ...

  3. iOS 的单例模式 dispatch_once

    iOS 的单例模式 dispatch_once 有些变量仅仅须要初始化一次(如从文件里读取配置參数.读取设备型号等等),能够使用dispatch_once来进行读取优化.保证仅仅调用API一次,以后就 ...

  4. 【iOS】单例模式

    单例模式在软件开发中经常用到,在iOS系统framework也很多地方用到单例模式,例如 [NSUserDefaults standardUserDefaults], [NSBundle mainBu ...

  5. iOS设计模式-单例模式

    (一)什么是单例模式(Singleton) 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点 *最初的定义是在<设计模式>(Addison-Wesley)中 解读 1> ...

  6. Objective-C(iOS)严格单例模式正确实现

    注:本文所有权归作者所有,转载请注明出处 当希望在一个应用程序中某个类的对象只能存在一个的时候就可以考虑用单例模式来实现,单例模式在C++中比较容易实现(只需把构造函数声明为private),而在Ob ...

  7. iOS开发-单例模式的解读

    现在网上的有很多人写单例模式,一个很基本的东西但是版本也有很多,新人看了难免有些眼花缭乱的感觉.自己最新比较闲,也过来写一些自己的心得. 在往下看之前,我们要明白一点,那就是在什么情况下我们才要用到单 ...

  8. iOS设计模式——单例模式

    单例模式用于当一个类只能有一个实例的时候, 通常情况下这个“单例”代表的是某一个物理设备比如打印机,或是某种不可以有多个实例同时存在的虚拟资源或是系统属性比如一个程序的某个引擎或是数据.用单例模式加以 ...

  9. iOS开发单例模式 dispatch_once

    什么是单例 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源 ...

随机推荐

  1. 解决连不上dl.google.com和dl-ssl.google.com

    http://ping.chinaz.com/ 开发android遇到的最大问题就是Google被墙了,而我们的sdk又需要通过dl.google.com和dl-ssl.google.com去下载一些 ...

  2. fullcalendar插件日程管理

    日程管理-fullcalendar插件用法   前言 本文分享fullcalendar用法,最后面提供代码下载 说到日程管理,基于JQuery的插件FullCalendar当之无愧,完整的API稳定和 ...

  3. 【LOJ】#2082. 「JSOI2016」炸弹攻击 2

    题解 想到n3发现思路有点卡住了 对于每个发射塔把激光塔和敌人按照极角排序,对于一个激光塔,和它转角不超过pi的激光塔中间夹的敌人总和就是答案 记录前缀和,用two-Points扫一下就行 代码 #i ...

  4. PHP rabbitmq扩展安装

    转载自: https://www.jianshu.com/p/65490900a937 安装rabbitmq的php扩展 1.安装扩展依赖库##### 注意:扩展是C写的,由于C与RabbitMQ通信 ...

  5. node.js之nodemon 代码热更新 修改代码后服务器自动重启

    1.安装nodemon: npm install -g nodemon //全局安装 npm install nodemon --save //局部安装 2.在项目根目录下创建 nodemon.jso ...

  6. 007.SMB其他应用

    一 目录权限 系统权限需要对共享目录生效 samba服务器权限也会对共享目录生效 当用户过多权限交叉的时候,建议使用系统权限控制共享目录权限,而不建议采用samba权限来控制 例如: [work] p ...

  7. 墨者学院靶场之PHP代码分析溯源(第1题)

    申请靶场环境后 点开题目 一段奇怪的PHP代码 因为我自己电脑重装了win10系统,php+apache+mysql的环境本地主机觉得没必要弄了,于是我们用在线的PHP编码(百度一下到处都是) 复制进 ...

  8. C#简单的通用分页

    通用分页技术分析 需要返回不同的类型的数据--采用泛型实现该操作 需要提供不同的方法 上一页 上一页 第一页 最后一页 跳转到指定页 Demo 代码 using System; using Syste ...

  9. Xamarin iOS教程之视图显示图像

    Xamarin iOS教程之视图显示图像 Xamarin iOS显示图像 在主视图中显示一个图像,可以让开发者的应用程序变的更有趣,例如,在一些应用程序开始运行时,都会通过图像来显示此应用程序的玩法或 ...

  10. 折腾一天安装Centos7,以及后面恢复Win7引导的曲折历程

    一.下载centos 7 livecd iso 访问镜像网站,http://mirrors.aliyun.com/centos/7.0.1406/isos/x86_64/ 或者直接下载:http:// ...