Objective-C中的单例模式

    ​    ​单例模式算是设计模式中比较简单的一种吧,设计模式不是只针对某种编程语言,在C++, Java, PHP等其他OOP语言也有设计模式,笔者初接触设计模式是通过《漫谈设计模式》了解的。这本书中是用java写的,个人感觉拜读完这本书以后虽然有不理解的地方但还是收获蛮大的。上面提到依赖注入,控制翻转的时候,没大看懂,当学习到Strut,Spring, Hibernate的东西的时候才略懂略懂。不过在23种设计模式里面单例模式还是算比较好理解的, 那么在OC中又是怎么来表示单例模式的呢?下面会结合着代码,理解一下OC中得单例模式。

    ​    ​首先得了解什么是单例模式,用大白话说,单例模式就是在程序中这个类只对应着一个实例,这就是单例模式,单例模式一般用全局静态对象来实现。下面我们会建立一个生成单例的类SingletonClass,在实现文件中定义各种方法来实现我们的单例模式。

    ​    ​1.单例模式一般用全局静态对象来实现,所以我们在SingletonClass.m中定义一个静态全局变量是少不了的

1 2

//定义静态全局变量 static SingletonClass *single = nil;

    ​    ​2.上面的静态变量是定义在实现文件中的所以是私有的,要想获取该类的实例得有个getInstance方法来获取实例,在给静态变量分配内存空间之前首先要判断是否已经分配过啦,确保单例,如果分配过了就不分配了。

1 2 3 4 5 6 7 8 9

//获取静态全局对象 +(id)getInstance {     //如果没有生成对象,则为静态全局变量分配内存     if (single == nil) {         single = [[SingletonClass alloc] init];     }     return single; }

    ​    ​

    ​    ​3.为了防止用户通过alloc和new来实例化对象,因此我们要对类方法allcoWithZone进行重写

1 2 3 4 5 6 7 8

//防止通过alloc或者new来创建新的对象我们要重写allocWithZone +(id)allocWithZone:(NSZone *)zone {     if (single == nil) {         single = [[super allocWithZone:zone] init];     }     return single; }

    ​    ​4.为了防止用户把单例进行深浅拷贝,我们需要重写copyWithZone方法和mutableCopyWithZone方法,在重写方法之前我们的单例类必须遵循协议NSCoping和NSMutableCoping协议

    ​    ​遵循协议代码如下:

1 2 3 4 5 6 7 8 9

@interface SingletonClass : NSObject<NSCopying, NSMutableCopying>   //单例中获取单例对象的方法 +(id) getInstance;   //单例测试方法 -(void) singletonFunction;   @end

    ​    ​重写copyWithZone方法

1 2 3 4 5

//为了防止通过copy来创建新的实例我们要重写copyWithZone; -(id)copyWithZone:(NSZone *)zone {     return self; }

    ​    ​重写mutableCopyWithZone方法

1 2 3 4

-(id)mutableCopyWithZone:(NSZone *)zone {     return self; }

    ​5.防止用户把创建的单例dealloc,我们需要重写retainCount方法

1 2 3 4 5

//重写retainCount方法,防止被dealloc,返回最大值 -(NSUInteger) retainCount {     return NSUIntegerMax; }

    ​6. 重写release,autorelease, retain方法

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

//重写retain,引用计数不变 -(id) retain {     return self; }   //重写release -(oneway void) release { }   //重写autorelease -(id) autorelease {     return self; }

    ​至此我们的单例模式基本创建完毕,下面开始我们的测试吧;

    ​在main函数中的代码如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

//单例模式的测试 SingletonClass *single1 = [SingletonClass getInstance]; SingletonClass *single2 = [SingletonClass new]; SingletonClass *single3 = [[SingletonClass alloc] init]; SingletonClass *single4 = [single1 copy]; SingletonClass *single5 = [single1 mutableCopy]; SingletonClass *single6 = [single1 retain]; [single1 release];   [single1 singletonFunction]; NSLog(@"single_retainCount = %lu", single1.retainCount);   //输出地址 NSLog(@"getInstance     single1_P = %p", single1); NSLog(@"new             single2_P = %p", single2); NSLog(@"allo            single3_P = %p", single3); NSLog(@"copy            single4_P = %p", single4); NSLog(@"mutableCopy     single5_P = %p", single5); NSLog(@"retain          single6_P = %p", single6);

    ​    ​运行结果如下:

1 2 3 4 5 6 7 8

2014-08-07 16:04:44.207 Memory[20664:303] singleton Ps: 我是单例模式中得测试方法!! 2014-08-07 16:04:44.207 Memory[20664:303] single_retainCount = 18446744073709551615 2014-08-07 16:04:44.207 Memory[20664:303] getInstance     single1_P = 0x100204690 2014-08-07 16:04:44.208 Memory[20664:303] new             single2_P = 0x100204690 2014-08-07 16:04:44.208 Memory[20664:303] alloC            single3_P = 0x100204690 2014-08-07 16:04:44.208 Memory[20664:303] copy            single4_P = 0x100204690 2014-08-07 16:04:44.209 Memory[20664:303] mutableCopy     single5_P = 0x100204690 2014-08-07 16:04:44.209 Memory[20664:303] retain          single6_P = 0x100204690

​    ​    ​单例的地址是不变的。

     上面是在非ARC模式下得单例模式,那么在ARC模式下我们应如何实现我们的单例模式呢,我们下面就会给出ARC下的单例模式,用下面的方法,因没有重写alloc,copy等方法,通过alloc还是可以给该对象分配一个新对象的,上面是线程不安全的,下面是线程安全的:

1 + (id)sharedSingleton {
2     static MySingleton *sharedSingleton = nil;
3     static dispatch_once_t onceToken;
4     dispatch_once(&onceToken, ^{
5         sharedSingleton = [[self alloc] init];
6     });
7     return sharedSingleton;
8 }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏陈满iOS

iOS·数据结构选型:在某数据结构中避免重复字符串元素(NSArray,NSSet,NSDictionary)

解析某博客或者书籍网站数据时:已知它的书籍首页URL地址,这个首页含有它的书籍目录及其章节的链接,APP想拉取它的目录节点,然而,该目录页面里面的章节可能有重复...

1282
来自专栏xx_Cc的学习总结专栏

iOS-单例模式写一次就够了

2375
来自专栏IT技术精选文摘

ZooKeeper 分布式锁实现

1722
来自专栏程序生活

Python pickle的使用pickle简介实例参考资料

pickle模块是对Python对象结构进行二进制序列化和反序列化的协议实现,就是把Python数据变成流的形式。

811
来自专栏進无尽的文章

简述OC语言

对于一门语言的学习是需要时间领悟的,而对于一些原理性的问题,我们需要清楚其核心思想,知其然而知其所以然,这样才能有利于自己的后续发展。本文只是简述,没有面面具到...

2262
来自专栏wOw的Android小站

[设计模式]之三:单例模式

还是试想一个情景:现在有一个自定义对话框。当主界面上的按钮被点击后,弹出对话框。 一般的设计思路是这样的:

781
来自专栏進无尽的文章

RunTime 之其他实践运用

有关Runtime的知识总结,我本来想集中写成一篇文章的,但是最后发现实在是太长,而且不利于阅读,最后分成了如下几篇:

1153
来自专栏五毛程序员

五毛的cocos2d-x学习笔记07-计时器、数据读写、文件读写

2595
来自专栏岑志军的专栏

KVO详解及底层实现

1482
来自专栏Python研发

Django之Model世界

django为使用一种新的方式,即:关系对象映射(Object Relational Mapping,简称ORM)

1292

扫码关注云+社区

领取腾讯云代金券