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

  当希望在一个应用程序中某个类的对象只能存在一个的时候就可以考虑用单例模式来实现,单例模式在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. 用shader使图片背景透明

    转自:http://blog.csdn.net/dawn_moon/article/details/8631783 好吧,终于抽时间写这篇文章了. 手头上有很多人物行走图,技能特效图等,但这些图都有个 ...

  2. Codeforces Round #185 (Div. 2) A. Whose sentence is it? 水题

    A. Whose sentence is it? Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/ ...

  3. Codeforces Round #286 (Div. 1) D. Mr. Kitayuta's Colorful Graph 并查集

    D. Mr. Kitayuta's Colorful Graph Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/ ...

  4. BZOJ 4247 挂饰 背包DP

    4247: 挂饰 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id ...

  5. c# winform 把彩色图片转换为灰色的图片,变灰,灰度图片,速度很快,safe,unsafe

    把彩色图片转换为灰色的图片,直接用.net接口遍历每个像素点转换的效率非常低,800K的图片65万像素我的电脑要用5分钟,而用了unsafe,速度提高了几千倍,同样的图片只用了0.几秒 附一个常用的遍 ...

  6. 转自邓凡平 《深入理解Android:Wi-Fi,NFC和GPS》章节连载[节选]--第七章 深入理解Wi-Fi P2P部分节选

    本章主要内容: 介绍Wi-Fi P2P相关知识: 介绍Android中WifiP2pService.wpa_supplicant的相关代码. 7.1  概述 承接第6章介绍的WSC,本章将继续介绍Wi ...

  7. ural 1993 This cheeseburger you don't need

    顺次存到{} [] () 遇到逗号就处理下,最后处理逗号之后的 #include <iostream> #include <cstring> #include <stri ...

  8. gcc中不同namespace中同名class冲突时

    正常情况下,编译器都会报错,提示你有两个候选类,让你明确的选择一个. 比如我的情况,我自己设计了一个类Message, 然后在某个文件里面引用了它.但是我的文件中又引入了mongodb的头文件,非常不 ...

  9. PHP对大文件的处理思路

    需求: 现有一个1G左右的日志文件,大约有500多万行, 用php返回最后几行的内容. 在php中,对于文件的读取时,最快捷的方式莫过于使用一些诸如file.file_get_contents之类的函 ...

  10. Helpers\Hooks

    Helpers\Hooks Add modules with hooks The hooks helper allows modules to be created within the module ...