IOS设计模式第二篇之单例设计模式
现在我们的组件已经有组织了。你需要从其他的地方得到数据,你也可以创建一个API类管理数据这个下个设计模式单例里面介绍。
这个单例设计模式确保这个类仅仅拥有一个实例,并且为这个实例提供一个全局的访问点。当的题词需要的时候他可以用懒加载创建一个单例。
注意:apple用了很多的单例:[NSUserDefaults standardUserDefaults],[UIApplication sharedApplication], [UIScreen mainScreen], [NSFileManager defaultManager]他们都是返回一个单例对象。
我们很想知道为什么如如果有不止一个类的实例存在。代码和内存很便宜多吗?
有些类需要存在一个实例例如:不需要有很多实例存在。除非你想写很多日志文件。或者获得一个全局配置的句柄类:很容易类在线程安全的情况下来共享资源。例如一个配置文件,如果有很多类同时修改这个配置文件。
怎么使用单例设计模式呢?
看看下面的图表类:

上面的图片展示了一个Logger类有一个单一的属性是单独的一个实例并且有两个方法sharedInstance和 init。
首先一个客户端发送sharedInstance消息这个属性实例还没有实例化,因此你需要给这个类创建一个新的实例并且返回一个引用给他。
然后你调用sharedInstance实例很快返回没有任何初始化。这个逻辑保证你仅仅有一个实例存在任何时候。
我们将要实现这个设计模式通过创建一个单例类来管理专辑数据。
你需要注意一个文件夹叫API在这个项目,你放到这里面的所有的类都是为了你的应用服务的。在这个文件夹里面创建一个继承与NSObject的LibraryAPI类。
打开libraryAPI头文件,写上以下代码:
@interface libraryAPI : NSObject
+(libraryAPI)shareInstance;
@end
然后到libraryAPI.m的实现文件里面@implementation后面写上:
+ (LibraryAPI*)sharedInstance
{
// 1
static LibraryAPI *_sharedInstance = nil;
// 2
static dispatch_once_t oncePredicate;
// 3
dispatch_once(&oncePredicate, ^{
_sharedInstance = [[LibraryAPI alloc] init];
});
return _sharedInstance;
}
1:定义一个静态变量来保存你类的实例确保在你的类里面保持全局。
2:定义一个静态的dispatch_once_t变量来确保这个初始化存在一次。
3:用GCD来执行block初始化libraryAPI实例。这是单例设计模式的本质。这个初始化不在被调用这个类已经被初始化。并且是线程安全的。
下次调用sharedInstance,这个代码里面的dispatch_once block不再执行由于已经执行一次,并且之前创建libraryAPI你已经得到一个引用。
注意:如果你想更多了解GCD可以参考 Multithreading and Grand Central Dispatcha和 How to Use Blocks 教程。
现在你有一个单例对象的入口点来管理专辑。下一步创建一个类来管理持久化你的library数据。
在API文件夹里面创建一个继承NSObject的新类PersistencyManager。
在PersistencyManager头文件导入#import "Album.h"
并且在@interface后面写上:
- (NSArray*)getAlbums;
- (void)addAlbum:(Album*)album atIndex:(int)index;
- (void)deleteAlbumAtIndex:(int)index;
以上三个方法的原型是处理专辑的数据。
打开PersistencyManager.m并且添加下面的代码到@implementation后面:
@interface PersistencyManager () {
// an array of all albums
NSMutableArray *albums;
}
给这个类添加一个延展,这是给一个类添加私有方法和属性的一个方式因此别的类是不能访问的。在这里你定义一个NSMutableArray来存储专家数据。这个可变数组的目的是便于添加和删除专辑。
现在在PersistencyManager实现文件里面添加:
- (id)init
{
self = [super init];
if (self) {
// a dummy list of albums
albums = [NSMutableArray arrayWithArray:
@[[[Album alloc] initWithTitle:@"Best of Bowie" artist:@"David Bowie" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_david%20bowie_best%20of%20bowie.png" year:@"1992"],
[[Album alloc] initWithTitle:@"It's My Life" artist:@"No Doubt" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_no%20doubt_its%20my%20life%20%20bathwater.png" year:@"2003"],
[[Album alloc] initWithTitle:@"Nothing Like The Sun" artist:@"Sting" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_sting_nothing%20like%20the%20sun.png" year:@"1999"],
[[Album alloc] initWithTitle:@"Staring at the Sun" artist:@"U2" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_u2_staring%20at%20the%20sun.png" year:@"2000"],
[[Album alloc] initWithTitle:@"American Pie" artist:@"Madonna" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_madonna_american%20pie.png" year:@"2000"]]];
}
return self;
}
在init你填充数组和五个样本唱片。
在PersistencyManager添加三个方法:
- (NSArray*)getAlbums
{
return albums;
}
- (void)addAlbum:(Album*)album atIndex:(int)index
{
if (albums.count >= index)
[albums insertObject:album atIndex:index];
else
[albums addObject:album];
}
- (void)deleteAlbumAtIndex:(int)index
{
[albums removeObjectAtIndex:index];
}
此时,您可能想知道PersistencyManager类的由来,因为它不是一个单例。LibraryAPI和PersistencyManager之间的关系将进一步探讨在下一节中,您将看外观设计模式。
来自英文教程翻译谢绝转载!!!未经允许不得转载维权必究!!!
IOS设计模式第二篇之单例设计模式的更多相关文章
- Java面试 - 什么是单例设计模式,为什么要使用单例设计模式,如何实现单例设计模式(饿汉式和懒汉式)?
什么是单例设计模式? 单例设计模式就是一种控制实例化对象个数的设计模式. 为什么要使用单例设计模式? 使用单例设计模式可以节省内存空间,提高性能.因为很多情况下,有些类是不需要重复产生对象的. 如果重 ...
- python学习【第十篇】单例设计模式
单例设计模式 目的:让类创建对象,在系统中只有唯一的实例,让每一次创建的对象返回的内存地址都是相同的. __new__方法 使用类名创建对象时,python解释器首先会调用__new__方法为对象分配 ...
- GOF设计模式之1:单例设计模式
1.单例设计模式核心作用: 保证一个类只有一个实例,并且提供了访问该实例的全局访问点 2.常见应用场景: window的任务管理器 项目中读取配置文件一般也是一个单例模式 数据库连接池的设计也是采用单 ...
- 初学者学Java设计模式(一)------单例设计模式
单例设计模式 单例设计模式是指一个类只会生成一个对象,优点是他可以确保所有对象都访问唯一实例. 具体实现代码如下: public class A { public static void main(S ...
- 【设计模式】Java之单例设计模式
1.单例设计模式:一个类只能有一个对象 1.1 创建单例类的步骤: 1.将构造方法私有化 2.创建私有的静态成员变量 3.共有的静态成员方法,提供当前的唯一对象 1.1 创建单例的两种方式: 1.饿汉 ...
- iOS——Swift开发中的单例设计模式(摘译,非原创)
最近在开发一个小的应用,遇到了一些Objective-c上面常用的单例模式,但是swift上面还是有一定区别的,反复倒来倒去发现不能按常理(正常的oc to swift的方式)出牌,因此搜索了一些帖子 ...
- 设计模式课程 设计模式精讲 8-10 单例设计模式-ThreadLocal线程单例
1 课程讲解 1.1 应用场景 2 代码演练 2.1 threadLocal应用 1 课程讲解 1.1 应用场景 多线程的时候: 使用同步锁使用时间换空间的方式,(线程排队时间比较长) 而使用thre ...
- 设计模式课程 设计模式精讲 8-8 单例设计模式-Enum枚举单例、原理源码解析以及反编译实战
1 课堂解析 2 代码演练 2.1 枚举类单例解决序列化破坏demo 2.2 枚举类单例解决序列化破坏原理 2.3 枚举类单例解决反射攻击demo 2.4 枚举类单例解决反射攻击原理 3 jad的使用 ...
- 设计模式课程 设计模式精讲 8-3 单例设计模式-DoubleCheck双重检查实战及原理解析
1 课程讲解 1.1 为何要使用双重检查 1.2 双重检查的缺点 1.3 指令重排序讲解 1.4 指令重排序比喻(自己理解) 1.5 如何解决指令重排序问题 2 代码演练 2.1 代码演练1(双重检查 ...
随机推荐
- OpenStack提交代码的review流程
本文整理向openstack社区提交代码的基本流程,以及社区一些介绍资料.如有转载,请注明出处! 先放张图说明一下OpenStack的code review的大体流程: 对OpenStack提交代码更 ...
- Objective-C MacOS以管理员权限执行程序
在MacOS下非常多操作是须要管理员权限的, 比方我们执行chmod.在命令行下能够使用sudo chmod来申请以管理员权限执行.可是使用XCode写的程序是不能使用sudo的. 须要自己写代码来申 ...
- C# IP地址与数字之间的互转
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Te ...
- 多线程---再次认识volatile,Synchronize,lock
在多线程中我们常用的保证共享变量的方法有很多,现在我们介绍其中的一种,volatile,也是效率最高的一种. 一 .volatile的意义: 为了确保共享变量能被正确和一 ...
- JavaScript对数组的处理(一)
数组创建 JavaScript中创建数组有两种方式,第一种是使用 Array 构造函数: var arr1 = new Array(); //创建一个空数组 var arr2 = new Array( ...
- Centos yum安装java jdk1.8
yum -y install java-1.8.0-openjdk* 安装后 java -version查看版本 检验是否安装成功. 其安装位置 /usr/lib/jvm/java-1.8.0-ope ...
- SQL2000系统表、存储过程、函数的功能介绍及应用
转自:http://blog.csdn.net/zlp321002/article/details/480925 ----系统表------------------------------------ ...
- 一分钟理清Vue-cli 代码构建步骤。
1. $ npm install vue -cli -g $ vue init webpack project-name $ cd project-name $ npm install $ npm r ...
- dedecms 自增数使用方法
[field:global name=autoindex runphp="yes"]@me=@me+1;[/field:global] {dede:global name=item ...
- 完美解决ListView中事件ItemCreated中使用ClientID导致插入数据失败
于昨天晚上看到视频做到这个例子,但是发现始终有错误,在ListView的ItemCreated事件中使用了ClientID则会导致数据插入数据库失败.当点击插入按钮时,网页就像点击F5刷新一样,无任何 ...