单例

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

所以我们要想办法阻止该类产生别的实例,一般语言中都会将构造函数写为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. MongoDB小结26 - 地理空间索引

    现在有一种查询变得越来越流行(尤其是移动设备):找到离当前位置最近的N个场所. MongoDB专为平面坐标查询做了专门的索引,称为地理空间索引. 同样需要用ensureIndex创建,不过,参数是两个 ...

  2. python 交互模式 方向键乱码问题解决

    python交互模式下通常用向上键来找到之前执行的命令,用左右键移动光标.这很方便.但有的时候这些键在按完后却会出现乱码. 本文只解决CentOS 6.4 下 python2.7.8 的乱码问题. 这 ...

  3. Linux纯Shell实现DNSPod动态域名

    http://www.anrip.com/post/872 开发背景: 公司有台嵌入式拨号上网设备,内置busybox和完整wget命令(支持https协议),但没有curl.python.ruby. ...

  4. IE網址欄快速輸入網址,“Ctrl+Enter”補齊“.com”

    繁體中文Windows,預設 IE 在網址列輸入 abc,然後按 Ctrl+Enter ,會跳到www.abc.com.tw, 但較常用的連結是www.abc.com,如何修改这一設定呢? 可以透過修 ...

  5. 网上Unused Index Script 脚本的问题

    曾经使用过网上下载的脚本查询没有使用过的Index比方SQL SERVER – 2008 – Unused Index Script – Download,事实上如今看起来这个脚本是有一些问题. 脚本 ...

  6. Python获得文件时间戳 异常访问监控 邮件定时提醒

    Python获得文件时间戳  异常访问监控 邮件定时提醒

  7. Swing中子元素截获MouseEvent问题

    在父元素中绑定MouseMotion监听,但是当鼠标在子元素中时父元素无法收到 这时候需要在子元素中绑定MouseMotion,然后使用: getParent().dispatchEvent(e); ...

  8. PSAM卡之常用APDU指令错误码【转】

    本文转载自:http://blog.csdn.net/lvxiangan/article/details/53933714 PSAM卡的内容交互,是通过APDU指令完成的,常见的APDU报文格式如下: ...

  9. HDU 4070 + 赤裸裸的贪心~~

    J - Phage War Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Phage ...

  10. [LeetCode] Construct Binary Tree from Inorder and Pretorder Traversal

    Given preorder and inorder traversal of a tree, construct the binary tree. Note:You may assume that ...