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

  当希望在一个应用程序中某个类的对象只能存在一个的时候就可以考虑用单例模式来实现,单例模式在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. ArcGIS Add-in开发(一)--获取选定要素的属性值

    刚刚接触AE开发,记录一下自己的学习心得! 欢迎大家一起交流探讨! 最近做大赛,突然想到可以让项目更加直观的操作,就在项目中加了幅底图(底图很简单) 我想在arcmap中选中相应的要素后,在后台通过写 ...

  2. MX记录查询

    nslookup set type=mx

  3. Codeforces Round #330 (Div. 2)D. Max and Bike 二分 物理

    D. Max and Bike Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/595/probl ...

  4. Crouton

    https://github.com/keyboardsurfer/Crouton https://github.com/GBouerat/Crouton https://github.com/ouy ...

  5. boost.asio源码剖析(一) ---- 前 言

    * 前言 源码之前,了无秘密.                                                       ——侯捷 Boost库是一个可移植.提供源代码的C++库,作 ...

  6. c++中的强制转换static_cast、dynamic_cast、reinterpret_cast的不同用法儿

    c++中的强制转换static_cast.dynamic_cast.reinterpret_cast的不同用法儿   虽然const_cast是用来去除变量的const限定,但是static_cast ...

  7. python 2.5源代码编绎

    VS C++项目中,选择工程项名称,右菜单中选择--->仅适用于项目---->仅生成(项目) 1.make_buildinfo,make_versioninfo make_buildinf ...

  8. Qt Quick实现的疯狂算数游戏

    使用 Qt Quick 写了个小游戏:疯狂算数.支持 Windows 和 Android 两个平台. 游戏简单,但牵涉到下面你的 Qt Quick 主题: 自己实现一个按钮 自适应分辨率 国际化 QM ...

  9. 如何判断一个数是否为素数(zt)

    怎么判断一个数是否为素数? 笨蛋的作法: bool IsPrime(unsigned n){    if (n<2)    { //小于2的数即不是合数也不是素数    throw 0;    ...

  10. openshift django目录结果

    blog├── README.md├── requirements.txt├── setup.py├── static├── wsgi│   ├── application│   ├── db.sql ...