【iOS 单例设计模式】底层解析与运用

一、单例设计名词解释:

(官方解释)单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例。
(形象比喻)程序 — 公司   单例实例 - 管理员   单例设计模式就好比一家公司在创建到垮台  只招一个管理员。并且至始至终不换。当然这个管理员有直属的职责方法  [UIApplication sharedApplication].keyWindow  这里的UIApplication 就是管理员   sharedApplication 就是唯一的管理员身份怎么  keyWindow就是该管理员的职责方法。

二、常见的单例设计模式

[UIApplication sharedApplication]

[UIScreen mainScreen]

[NSUserDefaults standardUserDefaults]

垃圾箱

任务管理器

三、单例设计的使用建议

1、节省内存开销。如果某个对象需要被多个其它对象使用,那可以考虑使用单例,因为这样该类只使用一份内存资源。

2、使用单例,可以确保其它类只获取类的一份数据( 变量值 )。

优点

1、提供了对唯一实例的受控访问。

2、由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。

3、因为单例模式的类控制了实例化的过程,所以类可以更加灵活修改实例化过程。

缺点

1、由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。

2、单例类的职责过重,在一定程度上违背了“单一职责原则”。

四、单例设计实践

1、线程不安全写法

 #import "DanliManger.h"

 static DanliManger *danliManger = nil; //定义一个全局的对象
@implementation DanliManger + (DanliManger *)shareManger { //此实例方法线程不安全,在多个实例同时加载的情况下。实例会同时创建
if (!danliManger) {
danliManger = [[DanliManger alloc] init];
} return danliManger;
} @end

运行结果:

//执行方法
DanliManger *A = [DanliManger shareManger];
DanliManger *B = [DanliManger shareManger];
DanliManger *C = [[DanliManger alloc] init];
DanliManger *D = [[DanliManger alloc] init];
NSLog(@"\nA:%@\nB:%@\nC:%@\nD:%@",A,B,C,D); //下面是运行结果
A:<DanliManger: 0x17420ab90>
B:<DanliManger: 0x17420ab90>
C:<DanliManger: 0x17420aba0>
D:<DanliManger: 0x17420abb0>

2、线程安全写法(推荐)

 #import "DanLiManager_2.h"

 @implementation DanLiManager_2

 + (DanLiManager_2 *)shareManager {

     static dispatch_once_t once;
static DanLiManager_2 *manager;
dispatch_once(&once, ^{ //线程只会执行一次,线程安全
manager = [[DanLiManager_2 myAlloc] init];
}); return manager;
} +(instancetype)myAlloc{
return [super allocWithZone:nil];
} +(instancetype)alloc{
NSAssert(, @"这是一个单例对象,请使用+(ZYHPayManager *)sharedMamager方法");
return nil;
}
+(instancetype)allocWithZone:(struct _NSZone *)zone{
return [self alloc];
} + (id)copy{
NSLog(@"这是一个单例对象,copy将不起任何作用");
return self;
} +(instancetype)new{
return [self alloc];
} @end

运行结果:

 1 //执行方法
2 DanLiManager_2 *A21 = [DanLiManager_2 copy];
3 DanLiManager_2 *A211 = [DanLiManager_2 new];
4 DanLiManager_2 *A2 = [DanLiManager_2 shareManager];
5 DanLiManager_2 *B2 = [DanLiManager_2 shareManager];
6 DanLiManager_2 *C2 = [[DanLiManager_2 alloc] init];
7 DanLiManager_2 *D2 = [[DanLiManager_2 alloc] init];
8 NSLog(@"a12 %@ : a211%@",A21, A211);
9 NSLog(@"\nA2:%@\nB2:%@\nC2:%@\nD2:%@",A2,B2,C2,D2);
10
11 //运行结果
12 这是一个单例对象,copy将不起任何作用
13 a12 DanLiManager_2 : a211(null)
14 A2:<DanLiManager_2: 0x174015810>
15 B2:<DanLiManager_2: 0x174015810>
16 C2:(null)
17 D2:(null)

五、总结

从运行结果可以直观的看出。单例设计模式只有一个实例,线程安全。

【iOS 单例设计模式】底层解析与运用的更多相关文章

  1. iOS单例设计模式具体解说(单例设计模式不断完好的过程)

    在iOS中有非常多的设计模式,有一本书<Elements of Reusable Object-Oriented Software>(中文名字为<设计模式>)讲述了23种软件设 ...

  2. ios 单例设计模式

    单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类.单例可用性非常高,用于登录用户管理等可供全局调用. + (AccountMa ...

  3. iOS开发之单例设计模式(完整正确版本)

    单例的意思从字面上就可以略知一二,所谓单例就是确保在程序运行过程中只创建一个对象实例.可以用于需要被多次广泛或者说多次使用的资源中,比如我们常见的网络请求类.工具类以及其它管理类等.比如我iOS开发中 ...

  4. IOS中的单例设计模式

    单例设计模式是IOS开发中一种很重要很常用的一种设计模式.它的设计原理是无论请求多少次,始终返回一个实例,也就是一个类只有一个实例.下面是苹果官方文档中关于单例模式的图片: 如图所示,左边的图是默认的 ...

  5. iOS 中的单例设计模式

    单例设计模式:在它的核心结构中只包含一个被称为单例类的特殊类.例如文件管理中的NSUserDefault,应用程序中的UIApplication,整个应用程序就这一个单例类,负责应用程序的一些操作,单 ...

  6. IOS设计模式第二篇之单例设计模式

    现在我们的组件已经有组织了.你需要从其他的地方得到数据,你也可以创建一个API类管理数据这个下个设计模式单例里面介绍. 这个单例设计模式确保这个类仅仅拥有一个实例,并且为这个实例提供一个全局的访问点. ...

  7. Java设计模式—单例设计模式(Singleton Pattern)全然解析

    转载请注明出处:http://blog.csdn.net/dmk877/article/details/50311791 相信大家都知道设计模式,听的最多的也应该是单例设计模式,这种模式也是在开发中用 ...

  8. GOF设计模式之1:单例设计模式

    1.单例设计模式核心作用: 保证一个类只有一个实例,并且提供了访问该实例的全局访问点 2.常见应用场景: window的任务管理器 项目中读取配置文件一般也是一个单例模式 数据库连接池的设计也是采用单 ...

  9. Servlet以及单例设计模式

    1.Servlet概述 a)Servlet,全城是Servlet Applet,服务器端小程序,是一个接口,定义了若干方法,要求所有的Servlet必须实现. b)Servlet用于接收客户端的请求, ...

随机推荐

  1. 《锋利的jQuery(第2版)》笔记-第2章-jQuery选择器

    选择器是jQuery的根基,在jQuery中,对事件处理.遍历DOM和Ajax操作都依赖于选择器.熟练使用选择器,不仅可以简化代码,而且可以达到事半功倍的效果. 2.1 jQuery选择器是什么 1. ...

  2. JAVA过滤器

    对于get请求和post请求全局过滤: 自己创建一个类,实现HttpServletRequestWrapper接口 package com.dh.deno; import java.io.Buffer ...

  3. js构造函数的方法与原型prototype

    把方法写在构造函数内的情况我们简称为函数内方法,把方法写在prototype属性上的情况我们简称为prototype上的方法 函数内的方法: 使用函数内的方法我们可以访问到函数内部的私有变量,如果我们 ...

  4. Linux软件包管理

    Linux软件包管理 Linux软件包管理主要有2类:是二进制包管理.源码包管理 二进制包管理 主要有RPM和YUM两种 RPM包管理 安装 --ivh:-v ,-vv,-vvv显示的安装信息依次详细 ...

  5. Azure的负载均衡机制

    负载均衡一直是一个比较重要的议题,几乎所有的Azure案例或者场景都不可避免,鉴于经常有客户会问,所以笔者觉得有必要总结一下. Azure提供的负载均衡机制,按照功能,可以分为三种:Azure Loa ...

  6. bind绑定参数

    const curry = (fn) => (...args)=>fn.bind(null,...args); const split = curry((splitOn, str) =&g ...

  7. 移动端视网膜(Retina)屏幕下1px边框线 解决方案

    原因: 因为Retine屏的分辨率始终是普通屏幕的2倍,1px的边框在devicePixelRatio=2的retina屏下会显示成2px. 但在IOS8中,已经支持0.5px了,那就意味着, 在de ...

  8. spring mvc controller间跳转 重定向 传参

    http://blog.csdn.net/jackpk/article/details/19121777/

  9. 关于iframe

    iframe一般用来嵌套其他页面来使用 1.如何使用? <iframe id="iframe1" src="2.html" frameborder=&qu ...

  10. CMake学习笔记

    C++开发者必备技能CMake  先简单介绍一下,CMake是一个跨平台的编译工具,它可以根据不用的平台,不同的编译环境,生成不同的MakeFile,从而控制编译的过程. 使用CMake的步骤: 1. ...