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(双重检查 ...
随机推荐
- TCP/IP,http,socket,长连接,短连接——小结(转)
概要: 之前对这几个概念有点糊涂,查阅了些资料,稍微概括下他们的区别吧.如有错误,请拍~~~ 先看图: TCP/IP是什么? TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层. 在 ...
- Maven快照
大型应用软件一般由多个模块组成,一般它是多个团队开发同一个应用程序的不同模块,这是比较常见的场景.例如,一个团队正在对应用程序的应用程序,用户界面项目(app-ui.jar:1.0) 的前端进行开发, ...
- (转)ffmpeg 中 av_read_frame_internal分析
作者: chenwei1983 时间: 2012-3-5 04:21 PM标题: ffmpeg 中 av_read_frame_internal分析 ...
- jQuery 文件上传插件:uploadify、swfupload
jQuery 文件上传插件: uploadify.swfupload
- Python内部机制。
type ,object ,__class__ ,__bases__ ,__metaclass__ , -------------------------不明白的地方----------------- ...
- Saltstack配置管理
制作简单初始化模块(在minion主机安装软件): 1.定义master配置文件file_roots [root@localhost~]# cat /etc/salt/master file_root ...
- win10 禁用Defender
cmd reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" /v "Dis ...
- C# WinForm下,隐藏主窗体的方法
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- 阿里云Redis开发规范[转]
一.键值设计 1. key名设计 (1)[建议]: 可读性和可管理性 以业务名(或数据库名)为前缀(防止key冲突),用冒号分隔,比如业务名:表名:id ugc:video:1 (2)[建议]:简洁性 ...
- Vue中计算属性与class,style绑定
var vm=new Vue({ el:'#app', data:{ a:2, }, computed:{ //这里的b是计算属性:默认getter b:{ get:function(){ retur ...