注:本文所有权归作者所有,转载请注明出处  

  当希望在一个应用程序中某个类的对象只能存在一个的时候就可以考虑用单例模式来实现,单例模式在C++中比较容易实现(只需把构造函数声明为private),而在Objective-C中对象可以通过NSObject的alloc来产生,所以需要编写一些额外的代码来确保对象的唯一性,考虑到现在编写iOS APP代码几乎都是ARC方式,且GCD也已经被用烂了,故本文给出一种利用GCD技术来实现严格单例模式的ARC版本,具体代码如下所示,所有的注意点都写在了注释里面:

 Singleton.h
@interface Singleton : NSObject
@property(nonatomic,strong) NSString *name;
+(Singleton*)defaultManager;
@end Singleton.m
@implementation Singleton
//单例类的静态实例对象,因对象需要唯一性,故只能是static类型
static Singleton *defaultManager = nil; /**单例模式对外的唯一接口,用到的dispatch_once函数在一个应用程序内只会执行一次,且dispatch_once能确保线程安全
*/
+(Singleton*)defaultManager
{
static dispatch_once_t token;
dispatch_once(&token, ^{
if(defaultManager == nil)
{
defaultManager = [[self alloc] init];
}
});
return defaultManager;
} /**覆盖该方法主要确保当用户通过[[Singleton alloc] init]创建对象时对象的唯一性,alloc方法会调用该方法,只不过zone参数默认为nil,因该类覆盖了allocWithZone方法,所以只能通过其父类分配内存,即[super allocWithZone:zone]
*/
+(id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t token;
dispatch_once(&token, ^{
if(defaultManager == nil)
{
defaultManager = [super allocWithZone:zone];
}
});
return defaultManager;
}
//自定义初始化方法,本例中只有name这一属性
- (instancetype)init
{
self = [super init];
if(self)
{
self.name = @"Singleton";
}
return self;
} //覆盖该方法主要确保当用户通过copy方法产生对象时对象的唯一性
- (id)copy
{
return self;
} //覆盖该方法主要确保当用户通过mutableCopy方法产生对象时对象的唯一性
- (id)mutableCopy
{
return self;
}
//自定义描述信息,用于log详细打印
- (NSString *)description
{
return [NSString stringWithFormat:@"memeory address:%p,property name:%@",self,self.name];
}

测试代码如下:

 Singleton *defaultManagerSingleton =[Singleton defaultManager];
NSLog(@"defaultManagerSingleton:\n%@",defaultManagerSingleton);
Singleton *allocSingleton = [[Singleton alloc] init];
NSLog(@"allocSingleton:\n%@",allocSingleton);
Singleton *copySingleton = [allocSingleton copy];
NSLog(@"copySingleton:\n%@",copySingleton);
Singleton *mutebleCopySingleton = [allocSingleton mutableCopy];
NSLog(@"mutebleCopySingleton:\n%@",mutebleCopySingleton); //打印结果
-- ::34.722 Singleton[:] defaultManagerSingleton:
memeory address:0x7fa6d1591530,property name:Singleton
-- ::34.727 Singleton[:] allocSingleton:
memeory address:0x7fa6d1591530,property name:Singleton
-- ::34.727 Singleton[:] copySingleton:
memeory address:0x7fa6d1591530,property name:Singleton
-- ::34.727 Singleton[:] mutebleCopySingleton:
memeory address:0x7fa6d1591530,property name:Singleton

从打印结果来看通过 [Singleton defaultManager]、[[Singleton alloc] init]、[allocSingleton copy]、[allocSingleton mutableCopy]这四种方法生成的对象地址都是0x7fa6d1591530,即表明对象是同一个,也就实现了严格单例模式,加上GCD是线程安全的所以在多线程中也能保证对象的唯一性。

另:在学习Objective-C编写单例模式时看到网上好多人都借用苹果官方的实现方式,但我自己始终没搜到官方的实现Sample代码,如果你知道麻烦把网址给我发下,谢谢哈~

Objective-C(iOS)严格单例模式正确实现的更多相关文章

  1. iOS开发--单例模式

    单例模式在iOS开发中可能算是最常用的模式之一了,但是由于oc本身的语言特性,想要写一个正确的单例模式相对来说比较麻烦,这里我就抛砖引玉来聊一聊iOS中单例模式的设计思路.关于单例模式更多的介绍请参考 ...

  2. QF——iOS的单例模式

    iOS的单例模式: 单例,即为单个实例,确保一个类里只有一个实例,向整个系统提供一个唯一的实例. 甚至为了严格提供唯一的实例,通常只允许该类自己提供实例化的方法,不允许出现其他入口.这时我们通常得重写 ...

  3. iOS 的单例模式 dispatch_once

    iOS 的单例模式 dispatch_once 有些变量仅仅须要初始化一次(如从文件里读取配置參数.读取设备型号等等),能够使用dispatch_once来进行读取优化.保证仅仅调用API一次,以后就 ...

  4. iOS开发-单例模式的解读

    现在网上的有很多人写单例模式,一个很基本的东西但是版本也有很多,新人看了难免有些眼花缭乱的感觉.自己最新比较闲,也过来写一些自己的心得. 在往下看之前,我们要明白一点,那就是在什么情况下我们才要用到单 ...

  5. Objective C (iOS) for Qt C++ Developers(iOS开发,Qt开发人员需要了解什么?)

    Qt/C++开发人员眼中的Obj-C      对于我们第一次自己定义iOS应用来说,对于来自Qt/C++开发人员来说,我不得不学习Objective-C相关语法与知识 为了让读者可以更easy理解这 ...

  6. 【iOS】单例模式

    单例模式在软件开发中经常用到,在iOS系统framework也很多地方用到单例模式,例如 [NSUserDefaults standardUserDefaults], [NSBundle mainBu ...

  7. iOS设计模式-单例模式

    (一)什么是单例模式(Singleton) 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点 *最初的定义是在<设计模式>(Addison-Wesley)中 解读 1> ...

  8. iOS设计模式——单例模式

    单例模式用于当一个类只能有一个实例的时候, 通常情况下这个“单例”代表的是某一个物理设备比如打印机,或是某种不可以有多个实例同时存在的虚拟资源或是系统属性比如一个程序的某个引擎或是数据.用单例模式加以 ...

  9. iOS中 快速正确的安装 CocoaPods

    有问题或技术交流可以咨询!欢迎加入! 第一部分: CocoaPods 的安装 步骤1 - 安装 RVM RVM 是干什么的这里就不解释了,后面你将会慢慢搞明白. $ curl -L https://g ...

随机推荐

  1. C# 钩子HOOK专题(1)

    目录   基本概念 运行机制 钩子类型 作者 基本概念   钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程 ...

  2. Android访问WebService的两种方法

    首先解释一下WebService:WebService是一种基于SOAP协议的远程调用标准.通过WebService可以将不同操作系统平台,不同语言.不同技术整合到一起.详细见:http://baik ...

  3. Sysprep命令详解

    本主题描述了 Windows(R) 8 版本的系统准备 (Sysprep) 工具的命令行语法. 如果你打算创建安装映像以部署到不同的计算机上,则必须运行带有 /generalize 选项的 Syspr ...

  4. Excel设置数据有效性实现单元格下拉菜单的3种方法(转)

    http://blog.csdn.net/cdefu/article/details/4129136 一.直接输入: 1.选择要设置的单元格,譬如A1单元格: 2.选择菜单栏的“数据”→“有效性”→出 ...

  5. 【M20】协助完成“返回值优化(RVO)”

    1.方法返回对象,会导致临时对象的产生,这降低了效率,const Rational operator* (const Rational& lhs,Rational& rhs).有没有什 ...

  6. android 表情,软键盘冲突解决方案(仿微博等SNS应用)

    之前总想搞一下这个模块,可是由于忙碌总是推迟,现在就把这块好好的弥补过来,下面是我实现的思路.本人才疏学浅,还望大家不要见笑. 首先我们还是先看写示例:            上面应用应该不用我过多介 ...

  7. [Javascript] Other functor

    EventStream: You can use RxJS, BaconJS or any reactive programming lib you want: var id_s = map(func ...

  8. 深入探讨this指针

    深入探讨this指针   为了写这篇文章,准备了好长时间,翻遍了箱底的书籍.可是如今还是不敢放开手来写,战战兢兢.不是操心自己写错,而是唯恐自己错误误导别人.同一时候也希望这篇文章能给你一点收获.既然 ...

  9. iOS开发——UI_swift篇&UItableView实现移动单元格

    UItableView实现移动单元格   1,下面的样例是给表格UITableView添加单元格移动功能: (1)给表格添加长按功能,长按后表格进入编辑状态 (2)在编辑状态下,可以看到单元格后面出现 ...

  10. javascript遍历数组

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...