单例

和其它语言的单例产不多,可以说是最简单的一种设计模式了。但是有几个点需要注意下,单例就是一个类只有一个实例。

所以我们要想办法阻止该类产生别的实例,一般语言中都会将构造函数写为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(对象创建)的更多相关文章

  1. Android与设计模式——单例(Singleton)模式

    概念: java中单例模式是一种常见的设计模式.单例模式分三种:懒汉式单例.饿汉式单例.登记式单例三种. 单例模式有一下特点: 1.单例类仅仅能有一个实例. 2.单例类必须自己自己创建自己的唯一实例. ...

  2. java设计模式-单例(singleton)

    单例模式,是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例.即一个类只有一个对象实例 如何保证对象唯一性呢? 思想: ...

  3. go设计模式--单例singleton

    创建型第一个,使用TDD作的. singleton.go package singleton type Singleton interface { AddOne() int } type single ...

  4. OpenJDK源码研究笔记(十三):Javac编译过程中的上下文容器(Context)、单例(Singleton)和延迟创建(LazyCreation)3种模式

    在阅读Javac源码的过程中,发现一个上下文对象Context. 这个对象用来确保一次编译过程中的用到的类都只有一个实例,即实现我们经常提到的"单例模式". 今天,特意对这个上下文 ...

  5. 跨应用程序域(AppDomain)的单例(Singleton)实现

    转载自: 跨应用程序域(AppDomain)的单例(Singleton)实现 - CorePlex代码库 - CorePlex官方网站,Visual Studio插件,代码大全,代码仓库,代码整理,分 ...

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

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

  7. Java设计模式之 — 单例(Singleton)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/8860649 写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上 ...

  8. Java设计模式透析之 —— 单例(Singleton)

    写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上线后还可以帮助你分析数据.但是Java原生带有的System.out.println()方法却很少在真正的项目开发中使用,甚至像f ...

  9. java设计模式——单例(Singleton)模式

    在某些场景,你需要找到一个承担职责的对象,并且这个对象是他所属类的唯一实例.此时可以使用单例模式. 单例模式的意图是为了确保一个类有且仅有一个实例,并为他提供一个全局的访问点.创建一个担当独一无二角色 ...

随机推荐

  1. VMware配置从U盘启动

    很遗憾,VMware的BIOS不能识别USB启动设备,即使已经把USB设备连接上去. 解决这一问题的做法是直接添加硬盘,硬盘指向物理硬盘,即USB设置. 注意:Ubuntu下要设置这一功能需要使用su ...

  2. 使用Hexo搭建博客

    好长时间没在博客园写东西了,自己搭了一套博客,把自己的一些积累分享给大家,欢迎指正! 博客地址:http://www.baiguangnan.com 使用Hexo搭建自己的博客,可以参考这里:http ...

  3. Django学习系列之CSRF

    Django CSRF 什么是CSRF CSRF, Cross Site Request Forgery, 跨站点伪造请求.举例来讲,某个恶意的网站上有一个指向你的网站的链接,如果 某个用户已经登录到 ...

  4. golang 查询数据库操作

    SQL.Open only creates the DB object, but dies not open any connections to the database. If you want ...

  5. PLU Decomposition

    PLU分解的优点是,能够将Ax=b的矩阵,转换成Ly=b, Ux = y 的形式.当我们改变系数矩阵b时,此时因为矩阵L和U均是固定 的,所以总能高效的求出矩阵的解. // LU.cpp : Defi ...

  6. PHP导入和导出CSV文件

    CREATE TABLE `student` ( `id` ) NOT NULL auto_increment, `name` varchar() NOT NULL, `sex` varchar() ...

  7. 网络学习笔记:TCP/IP连网和Internet

    1.网关 由硬件和软件组成,实现不同网段间的数据传送. 常用路由器充当网关. 网关通常维护一份路由表,但只有少量的编址信息.它用这些信息把数据转发到知道更多信息的网关. 组成互联网骨干的网关称为核心网 ...

  8. 解决Hibernate4执行update操作,不更新数据的问题

    后台封装java对象,使用hibernate4再带的update,执行不更新数据,不报错. 下面贴出解决方法: 失败的方法 hibernate自带update代码:(失效) Session sessi ...

  9. curl HTTP_USER_AGENT

    [root@bigdata-server-01 ~]# curl 13.26.92.20array(27) { ["HTTP_USER_AGENT"]=> string(11 ...

  10. 10.6 Graph Test

    一套图论的练习题,各个方面都有挺好的 第一第二题有一定难度(来源POI),第三第四题比较水 但我并没考好 T1 特工 szp T2 洞穴 zaw T3 最短路 line T4 最小差异值 dvalue