Objective-C设计模式——单例Singleton(对象创建)
单例
和其它语言的单例产不多,可以说是最简单的一种设计模式了。但是有几个点需要注意下,单例就是一个类只有一个实例。
所以我们要想办法阻止该类产生别的实例,一般语言中都会将构造函数写为private。但是OC中的函数并没有限定符,所以我们需要用一些小技巧来屏蔽这一点。
应用场景
类只能有一个实例,而且必须从一个为人熟知的访问点对其进行访问,比如工厂方法。
这个唯一的实例只能通过类的子类化进行扩展,而且扩展的对象不会破坏客户端代码。
注意
1.OC中单例的实例变量要定义在.m文件
2.OC中单例需要重载allocWithZone:和copyWithZone:方法来防止创建别的实例。
3.单例创建要注意线程安全,不然就可能出现多个实例。
注意问题将会在Demo中讲解
Demo
首先先来看一个最常规,的不严谨的单例实现:
@implementation Singleton static Singleton *sharedInstance; -(Singleton *)sharedInstance
{
if(sharedInstance)
{
sharedInstance = [Singleton new];
}
return sharedInstance;
} @end
这看似好像是可以得到单例对象了,但是这可以说是单例的一种变形。绝不能说这就是单例,因为我们可以轻松地通过其他方式来创建对象。
所以我们还要我修改allocWithZone:和copyWithZone:方法(alloc 和 copy 方法实际上就是调用这两个方法)
-(id)copyWithZone:(NSZone *)zone
{
return [[self class] sharedInstance];
} +(id)allocWithZone:(struct _NSZone *)zone
{
return [self sharedInstance];
}
可是这就出现另一个问题,在sharedInstance方法里面我们实际调用过allocWithZone:(new 调用 alloc),但是它的alloc被我们重写了,这就会出现错误。所以我们需要修改sharedInstance方法
+(Singleton *)sharedInstance
{
if(sharedInstance)
{
sharedInstance = [[super allocWithZone:NULL] init];
}
return sharedInstance;
}
这样就可以顺利的返回单例了,而且无法通过其它方式产生实例对象。
看似完美了实际还会有问题出现,因为现在是非线程安全的,可能存在同一时间创建多个实例的情况,所以修改如下
+(instancetype)sharedInstance
{
static dispatch_once_t once;
dispatch_once(&once, ^{
sharedInstance = [[super allocWithZone:NULL] init];
});
return sharedInstance;
}
客户端代码如下:
Singleton *singleton = [Singleton sharedInstance];
Singleton *singleton2 = [[Singleton alloc] init];
Singleton *singleton3 = [singleton copy]; [singleton print];
[singleton2 print];
[singleton3 print];
输出结果:
-- ::32.797 Singleton[:] 0x7fff5fbff7a8
-- ::32.798 Singleton[:] 0x7fff5fbff7a8
-- ::32.798 Singleton[:] 0x7fff5fbff7a8
可以看到内存都指向了同一地址。
Objective-C设计模式——单例Singleton(对象创建)的更多相关文章
- Android与设计模式——单例(Singleton)模式
概念: java中单例模式是一种常见的设计模式.单例模式分三种:懒汉式单例.饿汉式单例.登记式单例三种. 单例模式有一下特点: 1.单例类仅仅能有一个实例. 2.单例类必须自己自己创建自己的唯一实例. ...
- java设计模式-单例(singleton)
单例模式,是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例.即一个类只有一个对象实例 如何保证对象唯一性呢? 思想: ...
- go设计模式--单例singleton
创建型第一个,使用TDD作的. singleton.go package singleton type Singleton interface { AddOne() int } type single ...
- OpenJDK源码研究笔记(十三):Javac编译过程中的上下文容器(Context)、单例(Singleton)和延迟创建(LazyCreation)3种模式
在阅读Javac源码的过程中,发现一个上下文对象Context. 这个对象用来确保一次编译过程中的用到的类都只有一个实例,即实现我们经常提到的"单例模式". 今天,特意对这个上下文 ...
- 跨应用程序域(AppDomain)的单例(Singleton)实现
转载自: 跨应用程序域(AppDomain)的单例(Singleton)实现 - CorePlex代码库 - CorePlex官方网站,Visual Studio插件,代码大全,代码仓库,代码整理,分 ...
- Java设计模式—单例设计模式(Singleton Pattern)全然解析
转载请注明出处:http://blog.csdn.net/dmk877/article/details/50311791 相信大家都知道设计模式,听的最多的也应该是单例设计模式,这种模式也是在开发中用 ...
- Java设计模式之 — 单例(Singleton)
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/8860649 写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上 ...
- Java设计模式透析之 —— 单例(Singleton)
写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上线后还可以帮助你分析数据.但是Java原生带有的System.out.println()方法却很少在真正的项目开发中使用,甚至像f ...
- java设计模式——单例(Singleton)模式
在某些场景,你需要找到一个承担职责的对象,并且这个对象是他所属类的唯一实例.此时可以使用单例模式. 单例模式的意图是为了确保一个类有且仅有一个实例,并为他提供一个全局的访问点.创建一个担当独一无二角色 ...
随机推荐
- Jmeter技巧
Jmeter参数化的4种方法 用Jmeter测试时包含两种情况的参数,一种是在url中,一种是请求中需要发送的参数. URL中的参数,如:http://blog.da-fang.com/index.p ...
- ubuntu系统下,下载Android源码
博主电脑的Windows的 是用的vmware装的ubuntu kylin.vmware随便找都能找到尽量安装最新版本号的,而unbuntu在官方站点下载即可了,安装vmware的时候建议关闭安全类 ...
- c# Winform实现中国省份地图
1.利用raphael.js IE下的VML和SVG实现矢量地图 2.JS调用c# Winform代码,代码 [System.Runtime.InteropServices.ComVisibleAtt ...
- 什么是sibling and tail recursive calls
1 tail call 在函数f中调用函数b,如果这个调用是函数f中执行的最后一条指令,那么这个调用就称为tail call. 例子: int foo(float a, float b) { ... ...
- frame pointer及其用途
1 什么是frame pointer frame pointer指向本函数栈帧顶,通过它可以找到本函数在进程栈中的位置.有专门的寄存器保存该值. 2 frame pointer有什么用 主要是back ...
- win32gui.EnumWindows my.os.EnumWindows.py
import win32guidef _MyCallback(hwnd, extra): windows = extra temp = [] temp.append(hex(hwnd)) temp.a ...
- bzoj5311: 贞鱼
还是年轻啊算的时候少乘一个4000被卡二分上界了...%%%%bright教我超级快速读D飞bzoj垃圾卡常数据 我们容易写出这样的DP方程:f[i][j]=f[k][j-1]+val(k+1,j) ...
- javaSE基础(二)
文件:文件是信息在计算机上的保存形式. 可控式异常:一种必须被处理或必须在可能产生异常的方法中给出声明的异常. 可控式异常的三种处理方式: 1)try...catch捕获 2)throws语句往上抛 ...
- xUnit随笔
XUnit入门 1.如果之前安装了xUnit.net Visual Studio Runner扩展包,通过"工具"菜单下的"扩展和更新"先将该扩展包卸载. 2. ...
- iOS开发——多线程
很多朋友都说iOS开发中,最难理解和学习的就是多线程,很多的原理实现都是通过log看到,也比较抽象,本人也是在多线程方面投入过很多脑细胞..无论这方面的知识掌握和应用起来是否轻松,牢固的基本功.正确的 ...