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 = 184467440737095516152014-08-07 16:04:44.207 Memory[20664:303] getInstance single1_P = 0x1002046902014-08-07 16:04:44.208 Memory[20664:303] new single2_P = 0x1002046902014-08-07 16:04:44.208 Memory[20664:303] alloC single3_P = 0x1002046902014-08-07 16:04:44.208 Memory[20664:303] copy single4_P = 0x1002046902014-08-07 16:04:44.209 Memory[20664:303] mutableCopy single5_P = 0x1002046902014-08-07 16:04:44.209 Memory[20664:303] retain single6_P = 0x100204690 |
单例的地址是不变的。
上面是在非ARC模式下得单例模式,那么在ARC模式下我们应如何实现我们的单例模式呢,我们下面就会给出ARC下的单例模式,用下面的方法,因没有重写alloc,copy等方法,通过alloc还是可以给该对象分配一个新对象的,上面是线程不安全的,下面是线程安全的:
+ (id)sharedSingleton {
static MySingleton *sharedSingleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedSingleton = [[self alloc] init];
});
return sharedSingleton;
}
Objective-C中的单例模式的更多相关文章
- C# 中实现单例模式
文章目录 简介 不安全线程的单例模式 简单安全线程带锁 双重检查 - 带锁 安全初始化 安全并且懒汉式静态初始化 带泛型的懒汉式单例 异常 提高效率 总结 简介 单例模式是软件工程中广为人知的设计模式 ...
- 转:C++中的单例模式
C++中的单例模式 单例模式也称为单件模式.单子模式,可能是使用最广泛的设计模式.其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享.有很多地方需要这样的功能模块, ...
- 浅谈iOS中的单例模式
iOS中的单例模式 就我本身理解而言,我认为的单例:单例在整个工程中,就相当于一个全局变量,就是不论在哪里需要用到这个类的实例变量,都可以通过单例方法来取得,而且一旦你创建了一个单例类,不论你 ...
- 理解Objective C 中id
什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...
- 浅谈Objective—C中的面向对象特性
Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...
- 关于JDK中采用单例模式的类
JDK设计模式应用——单例模式(Singleton) <JDK源码分析>的分支,讲解设计模式在jdk中使用. 我们从三个方面讲述,一是:jdk源码中的设计模式:二是:讲解设计模式(UML图 ...
- java中的单例模式与doublecheck
转自: http://devbean.blog.51cto.com/448512/203501 在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容易出现问题.下面就单 ...
- java中的单例模式与静态类
单例模式与静态类(一个类,所有方法为静态方法)是另一个非常有趣的问题,在<Java中有关单例模式的面试问题>博文中露掉了,由于单例模式和静态类都具有良好的访问性,它们之间有许多相似之处,例 ...
- 【译】在C#中实现单例模式
目录 介绍 第一个版本 --不是线程安全的 第二个版本 -- 简单的线程安全 第三个版本 - 使用双重检查锁定尝试线程安全 第四个版本 - 不太懒,不使用锁且线程安全 第五版 - 完全懒惰的实例化 第 ...
随机推荐
- 开启PHP的伪静态
1.检测Apache是否支持mod_rewrite 通过php提供的phpinfo()函数查看环境配置,通过Ctrl+F查找到“Loaded Modules”,其中列出了所有 apache2handl ...
- 李洪强iOS经典面试题155 - const,static,extern详解(面试必备)
李洪强iOS经典面试题155 - const,static,extern详解(面试必备) 一.const与宏的区别(面试题): const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽 ...
- 初识Scala反射
我们知道,scala编译器会将scala代码编译成JVM字节码,编译过程中会擦除scala特有的一些类型信息,在scala-2.10以前,只能在scala中利用java的反射机制,但是通过java反射 ...
- can't connect to mysql server on 'localhost'(10061)
在linux下安装Navicat,想说在windows下试一试phpmyadmin之外的mysql图形工具. 显示下载安装了mysql workbench,链接成功.然后又弄了一下输入法重启,想说试一 ...
- 谁说JavaScript容易?
你尝试过给一组数字排序吗? Javascript的sort()方法默认用来给数字排序 所以[1,2,5,10].sort()将会输出[1, 10, 2, 5]. 要正确的对数组进行排序的话,你可以使用 ...
- MVC和MVP的区别
MVC: Model - View - Controller MVP: Model - View - Presenter MVC和MVP到底有什么区别呢? 从上图可以看到在MVC里,View是可以直接 ...
- Android_SQLite数据库增删改查操作
一:什么是SQLite? 在Android平台上,集成了一个嵌入式关系型轻量级的数据库. 二:什么时候用的数据库? 有大量相似机构的数据需要存储时. 三:如何创建一个数据库? 1.创建一个Sqlite ...
- Response.StatusCode的HTTP状态代码列表
1xx - 信息提示这些状态代码表示临时的响应.客户端在收到常规响应之前,应准备接收一个或多个 1xx 响应. · 100 - Continue 初始的请求已经接受,客户应当继续发送请求的其余部分.( ...
- Servant:基于Web的IIS管理工具
Servant for IIS是个管理IIS的简单.自动化的Web管理工具.安装Servant的过程很简单,只要双击批处理文件Install Servant Service.bat,然后按照屏幕上的说 ...
- Hibernate 延迟加载原理
如何简单的理解延迟加载?开发中常见的org.hibernate.LazyInitializationException no session错误又是怎么产生的?下面通过一个简单的例子来解析一下 ...