单例模式的作用是解决“应用中只有一个实例”的一类问题。

(一)问题的提出 

  在一个iOS 应用的生命周期中,有时候我们只需要某个类的一个实例。例如,iOS 设备都有一个重力加速计硬件设备,要访问设备在x轴、y轴和z轴上的重力加速度,就必然要有一个类能够与硬件设备沟通来实时获得这些数据,这个类就是UIAccelerometer 。除了实时地获得数据,该类还能够保持x 轴、y轴和z 轴的状态。但是这个类只需要一个实例就够了,如果有多个实例,就会占用过多的内存。
再有,当应用程序启动时,应用的状态由UIApplication 类的一个实例维护,这个实例代表了整个“应用程序对象”,它只能是一个实例,其作用是实现应用程序中一些共享资源的访问和状态的保持等。

(二)实现原理

  单例模式一般会封装一个静态属性,并提供静态实例的创建方法,其UML类图如图1所示。

图1 单例设计模式类图

示例代码:

//Singleton.h
//
@interface Singleton : NSObject
+ (Singleton*)sharedManager;
@property (nonatomic ,strong) NSString* singletonData;
@end //Singleton.m
//
#import "Singleton.h"
@implementation Singleton
@synthesize singletonData = _singletonData;
static Singleton *sharedManager = nil;
+ (Singleton*)sharedManager
{ static dispatch_once_t once; dispatch_once(&once, ^{ sharedManager = [[self alloc] init]; }); return sharedManager;
}
@end

其中static Singleton *sharedManager 为静态变量,类方法为+ (Singleton*)sharedManager。
sharedManager 方法采用了GCD(Grand Central Dispatch)技术,这是一种基于C语言的多线程访问技术。在上述代码中,dispatch_once 函数就是由GCD提供的,它的作用是在整个应用程序生命周期中只执行一次代码块(^{…})。 dispatch_once_t 是GCD提供的结构体,使用时需要将GCD地址传给dispatch_once 函数。dispatch_once 函数能够记录该代码块是否被调用过。
  dispatch_once函数不仅意味着代码仅会被运行一次,而且还意味着此运行还是线程同步的。也就是说,当我们使用了dispatch_once函数时,就不再需要使用诸如@synchronized之类的语句。

  将以上单例实现代码,抽成宏,代码如下:

// @interface
#define singleton_interface(className) \
+ (className *)shared##className;// @implementation
#define singleton_implementation(className) \
static className *_instance; \
+ (id)allocWithZone:(NSZone *)zone \
{ \static dispatch_once_t onceToken; \dispatch_once(&onceToken, ^{ \_instance = [super allocWithZone:zone]; \}); \return _instance; \
} \
+ (className *)shared##className \
{ \static dispatch_once_t onceToken; \dispatch_once(&onceToken, ^{ \_instance = [[self alloc] init]; \}); \return _instance; \
}

(三)应用案例

  在Cocoa Touch框架中,有UIApplication、UIAccelerometer 、NSUserDefaults和NSNotificationCenter等单例类。另外,NSFileManager 和NSBundle 类虽然属于Cocoa框架的内容,但也可以在Cocoa Touch框架中使用(Cocoa框架中的单例类有NSFileManager 、NSBundle 、NSWorkspace和NSApplication 等)。

1. UIApplication

UIApplication 类的实例提供了应用程序的集中控制点来保持应用的状态。UIApplication 实例总是分配给应用程序委托对象(UIApplicationDelegate ),通过应用程序委托对象来响应低内存、应用启动、后台运行和应用终止等事件。在HelloWorld 案例中,AppDelegate 就是这个应用程序的委托对象,它实现了UIApplicationDelegate协议。

UIApplication 类有很多方法和属性,下面我们重点介绍其中几个。

  • + sharedApplication 方法。创建和获得UIApplication 实例的方法。
  • idleTimerDisabled属性。设定和获得“空闲时间禁止”的状态。idleTimerDisabled属性的默认值是NO,即默认情况下系统会锁定屏幕。当idleTimerDisabled = YES 时,则不会开启“空闲时间禁止”状态,系统不会锁定屏幕。开启这项设定需要谨慎,它会使你的应用比较耗电。
  • - openURL: 方法。可以打开一些内置的iOS 应用,其中包括打开浏览器、打开Google 地图、拨打电话、发送短信和发送E-mail 等。

打开浏览器的示例代码如下:

NSURL *url = [NSURL URLWithString:@"http://www.cnblogs.com/chars"];
[[UIApplication sharedApplication] openURL:url]; 

打开Google 地图时,实际上是通过内置浏览器来打开,示例代码如下:

NSString* searchQuery = @" 清华大学";
searchQuery = [searchQuery stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
NSString* urlString = [NSString stringWithFormat: @"http://maps.google.com/maps?q=%@", searchQuery];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]]; 

其中NSString 的stringByAddingPercentEscapesUsingEncoding方法将字符串转换为URL编码,例如 “%E6%B8%85%E5%8D%8E%E5%A4%A7%E5%AD%A6 ”是“清华大学”的 URL 编码。
拨打电话时,苹果官方要求使用该方法调用内置拨号程序,示例代码如下:

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://10010"]];

发送短信时,苹果官方要求使用该方法调用内置发送短信程序,示例代码如下:

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:10010"]]; 

发送E-mail 时,这种方式可以发送简单的不带附件的E-mail ,示例代码如下:

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto://eorient@sina.com"]];

2.   UIAccelerometer

  单例类UIAccelerometer 前面也讲过,它可以访问重力加速计硬件设备,实时获得设备在x 轴、y轴和z 轴方向上的重力加速度。

  + sharedAccelerometer方法是创建和获得UIAccelerometer实例的共享方法。

  与UIApplication类似,UIAccelerometer也有对应的委托对象,其委托对象为UIAccelerometerDelegate。UIAccelerometer 将实例分配给委托对象UIAccelerometerDelegate ,然后由委托对象响应重力加速计事件。

3.   NSUserDefaults

  单例类NSUserDefaults可以很方便地读取应用设置项目。

  + standardUserDefaults方法是创建和获得NSUserDefaults实例的静态方法。

4.   NSNotificationCenter

  单例类NSNotificationCenter提供信息广播通知,它采用观察者模式的通知机制。

  + defaultCenter 方法是创建和获得NSNotificationCenter实例的共享方法。

5.   NSFileManager

  NSFileManager 提供了访问文件系统的通用操作,可以定位、创建、复制文件和文件夹。在iOS 5和Mac OS X v10.7之后,它还可以管理存储在iCloud 上的数据。

  + defaultManager 方法是创建和获得NSFileManager 实例的方法。除了该方法外,创建NSFileMa nager对象时还可以使用实例构造方法– init。这两种方法有着比较大的差别,+ defaultManager方法总是返回相同的NSFileManager 对象,但如果要使用委托(NSFileManagerDelegate)完成基于文件的操作并接收通知,应该使用– init 方法创建一个新的实例,而不是使用共享的对象。

6.   NSBundle

  NSBundle 提供了动态加载(或卸载)可执行代码、定位资源文件以及资源本地化、访问文件系统等功能。

  + mainBundle方法是创建和获得NSBundle 实例的共享方法。

  单例模式无疑是Cocoa框架下最重要的设计模式之一。灵活而有机地运用设计模式,意味着编程工作的高效性和产品健壮性、安全性的提高。因此,我们应该要善于使用设计模式,将自己的开发经验与代码、设计模式完美融合起来,提高软件代码质量。

转载于:https://www.cnblogs.com/chars/p/5006959.html

iOS学习之单例模式相关推荐

  1. 【原】iOS学习之事件处理的原理

    在iOS学习23之事件处理中,小编详细的介绍了事件处理,在这里小编叙述一下它的相关原理 1.UITouch对象 在触摸事件的处理方法中都会有一个存放着UITouch对象的集合,这个参数有什么用呢? ( ...

  2. iOS学习——核心动画之Layer基础

    iOS学习--核心动画之Layer基础 1.CALayer是什么? CALayer我们又称它叫做层.在每个UIView内部都有一个layer这样一个属性,UIView之所以能够显示,就是因为它里面有这 ...

  3. OpenCV for Ios 学习笔记(4)-标记检测1

    本文原始地址:OpenCV for Ios 学习笔记(4)-标记检测1 简单的标记经常是以白色块和黑色块构成的规则图形.因为我们预先知道这些因素,所以我们可以很容易检测标记. 如图: 首先,我们需要找 ...

  4. IOS学习笔记(九)之UIAlertView(警告视图)和UIActionSheet(操作表视图)基本概念和使用方法...

    IOS学习笔记(九)之UIAlertView(警告视图)和UIActionSheet(操作表视图)基本概念和使用方法 Author:hmjiangqq Email:jiangqqlmj@163.com ...

  5. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  6. iOS学习资源(一)

    用了印象笔记也很久了,这里就把自己整理的一些学习资源分享出来.需要共享印象笔记的小伙伴可以联系: shavekevin@gmail.com 我会把自己的工作笔记共享给大家,和大家一起学习,一起进步. ...

  7. iOS学习之iOS沙盒(sandbox)机制和文件操作(二)

    接上篇 iOS学习之iOS沙盒(sandbox)机制和文件操作(一) 我们看看如何获取应用程序沙盒目录.包括真机的沙盒的目录. 1.获取程序的Home目录 [cpp] view plaincopy N ...

  8. IOS学习之蓝牙4.0

    转载请注明出处 作者:小马 IOS学习也一段时间了,该上点干货了.前段时间研究了一下IOS蓝牙通讯相关的东西,把研究的一个成果给大家分享一下. 一 项目背景 简单介绍一下做的东西,设备是一个金融刷卡器 ...

  9. IOS学习之UINavigationController详解与使用(一)添加UIBarButtonItem

    转:http://blog.csdn.net/totogo2010/article/details/7681879 1.UINavigationController导航控制器如何使用 UINaviga ...

  10. ios学习--TableView详细解释

    2019独角兽企业重金招聘Python工程师标准>>> ios学习--TableView详细解释 分类: ios Object-C 2012-05-17 08:48  1714人阅读 ...

最新文章

  1. 《梦断代码Dreaming In Code》阅读笔记(三)
  2. 1024,咱们程序员过节了,疯狂送书
  3. 新浪微博一键关注代码
  4. 锤子科技犯过的构图错误你一定也犯过
  5. Python3各种进制之间的转换方法
  6. boost::two_graphs_common_spanning_trees用法的测试程序
  7. [智能架构系列]什么是Buddy智能开发框架
  8. ethereumjs/ethereumjs-common-3-test
  9. 欧式理论计算机科学,理论计算机科学中几个问题.ppt
  10. 如何获取当前显示的片段?
  11. java datediff函数_JPA Criteria 中 DATEDIFF 函数的使用
  12. 视觉slam十四讲课后习题ch3--5题
  13. CountDownLatch理解
  14. 浅谈计算机辅助数学教学论文,数学教师论文,关于计算机辅助数学教学的原则方式相关参考文献资料-免费论文范文...
  15. 网页自动加拼音html,HTML5给汉字加拼音收起展开组件的实现代码
  16. 高通MSM8953处理器(CPU)/骁龙625资料介绍
  17. C#数字黑洞之一(西绪福斯黑洞:123数字黑洞)
  18. 双线性光强插值(Gouraud明暗处理)学习笔记
  19. Python 负载均衡,数据轮询 hash字符串 hashlib
  20. 《交互式程序设计 第2版》一1.2.4 交互语言

热门文章

  1. mysql 数据增量备份_mysqlmysqldump数据备份和增量备份
  2. matlab 给参数赋值,未对输出参数赋值 求大神帮忙解惑
  3. mysql 主从复制延迟_什么情况会导致MySQL主从复制延迟?
  4. 鸿蒙安卓生态已经非常完善,鸿蒙前进一小步,生态却完善一大步,解决了替换安卓的第一个问题...
  5. hive中groupby优化_工作中总结的关于hive的优化方案
  6. 实战 Kaggle 比赛:狗的品种识别(ImageNet Dogs) 动手学深度学习v2 pytorch
  7. 算法:回溯和动态规划解决每次移动一步最终回到原地1269. Number of Ways to Stay in the Same Place After Some Steps
  8. 微型计算机主机作用,微型计算机的主机包括()。
  9. 输出单向链表中倒数第k个结点
  10. r5处理器_买完笔记本特别的卡?那是因为你买笔记本之前,处理器没选对