Objective-C中的单例模式
2015-12-18 12:51
387 查看
单例模式算是设计模式中比较简单的一种吧,设计模式不是只针对某种编程语言,在C++, Java, PHP等其他OOP语言也有设计模式,笔者初接触设计模式是通过《漫谈设计模式》了解的。这本书中是用java写的,个人感觉拜读完这本书以后虽然有不理解的地方但还是收获蛮大的。上面提到依赖注入,控制翻转的时候,没大看懂,当学习到Strut,Spring, Hibernate的东西的时候才略懂略懂。不过在23种设计模式里面单例模式还是算比较好理解的, 那么在OC中又是怎么来表示单例模式的呢?下面会结合着lusashi的代码,理解一下OC中得单例模式。
首先得了解什么是单例模式,用大白话说,单例模式就是在程序中这个类只对应着一个实例,这就是单例模式,单例模式一般用全局静态对象来实现。下面我们会建立一个生成单例的类SingletonClass,在实现文件中定义各种方法来实现我们的单例模式。
单例模式一般用全局静态对象来实现,所以我们在SingletonClass.m中定义一个静态全局变量是少不了的
//定义静态全局变量
static
SingletonClass
*single
= nil;
2.上面的静态变量是定义在实现文件中的所以是私有的,要想获取该类的实例得有个getInstance方法来获取实例,在给静态变量分配内存空间之前首先要判断是否已经分配过啦,确保单例,如果分配过了就不分配了。
//获取静态全局对象
+(id)getInstance
{
//如果没有生成对象,则为静态全局变量分配内存
if
(single
== nil)
{
single
= [[SingletonClass
alloc]
init];
}
return
single;
}
3.为了防止用户通过alloc和new来实例化对象,因此我们要对类方法allcoWithZone进行重写
//防止通过alloc或者new来创建新的对象我们要重写allocWithZone
+(id)allocWithZone:(NSZone
*)zone
{
if
(single
== nil)
{
single
= [[super
allocWithZone:zone]
init];
}
return
single;
}
4.为了防止用户把单例进行深浅拷贝,我们需要重写copyWithZone方法和mutableCopyWithZone方法,在重写方法之前我们的单例类必须遵循协议NSCoping和NSMutableCoping协议
遵循协议代码如下:
@interface
SingletonClass : NSObject
//单例中获取单例对象的方法
+(id)
getInstance;
//单例测试方法
-(void)
singletonFunction;
@end
重写copyWithZone方法
//为了防止通过copy来创建新的实例我们要重写copyWithZone;
-(id)copyWithZone:(NSZone
*)zone
{
return
self;
}
重写mutableCopyWithZone方法
-(id)mutableCopyWithZone:(NSZone
*)zone
{
return
self;
}
5.防止用户把创建的单例dealloc,我们需要重写retainCount方法
//重写retainCount方法,防止被dealloc,返回最大值
-(NSUInteger)
retainCount
{
return
NSUIntegerMax;
}
6. 重写release,autorelease, retain方法
//重写retain,引用计数不变
-(id)
retain
{
return
self;
}
//重写release
-(oneway
void)
release
{
}
//重写autorelease
-(id)
autorelease
{
return
self;
}
至此我们的单例模式基本创建完毕,下面开始我们的测试吧;
在main函数中的代码如下:
//单例模式的测试
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);
运行结果如下:
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还是可以给该对象分配一个新对象的,上面是线程不安全的,下面是线程安全的:
+
(id)sharedSingleton
{
static
MySingleton
*sharedSingleton
= nil;
static
dispatch_once_t
onceToken;
dispatch_once(&onceToken,
^{
sharedSingleton
= [[self
alloc]
init];
});
return
sharedSingleton;
}
首先得了解什么是单例模式,用大白话说,单例模式就是在程序中这个类只对应着一个实例,这就是单例模式,单例模式一般用全局静态对象来实现。下面我们会建立一个生成单例的类SingletonClass,在实现文件中定义各种方法来实现我们的单例模式。
单例模式一般用全局静态对象来实现,所以我们在SingletonClass.m中定义一个静态全局变量是少不了的
//定义静态全局变量
static
SingletonClass
*single
= nil;
2.上面的静态变量是定义在实现文件中的所以是私有的,要想获取该类的实例得有个getInstance方法来获取实例,在给静态变量分配内存空间之前首先要判断是否已经分配过啦,确保单例,如果分配过了就不分配了。
//获取静态全局对象
+(id)getInstance
{
//如果没有生成对象,则为静态全局变量分配内存
if
(single
== nil)
{
single
= [[SingletonClass
alloc]
init];
}
return
single;
}
3.为了防止用户通过alloc和new来实例化对象,因此我们要对类方法allcoWithZone进行重写
//防止通过alloc或者new来创建新的对象我们要重写allocWithZone
+(id)allocWithZone:(NSZone
*)zone
{
if
(single
== nil)
{
single
= [[super
allocWithZone:zone]
init];
}
return
single;
}
4.为了防止用户把单例进行深浅拷贝,我们需要重写copyWithZone方法和mutableCopyWithZone方法,在重写方法之前我们的单例类必须遵循协议NSCoping和NSMutableCoping协议
遵循协议代码如下:
@interface
SingletonClass : NSObject
//单例中获取单例对象的方法
+(id)
getInstance;
//单例测试方法
-(void)
singletonFunction;
@end
重写copyWithZone方法
//为了防止通过copy来创建新的实例我们要重写copyWithZone;
-(id)copyWithZone:(NSZone
*)zone
{
return
self;
}
重写mutableCopyWithZone方法
-(id)mutableCopyWithZone:(NSZone
*)zone
{
return
self;
}
5.防止用户把创建的单例dealloc,我们需要重写retainCount方法
//重写retainCount方法,防止被dealloc,返回最大值
-(NSUInteger)
retainCount
{
return
NSUIntegerMax;
}
6. 重写release,autorelease, retain方法
//重写retain,引用计数不变
-(id)
retain
{
return
self;
}
//重写release
-(oneway
void)
release
{
}
//重写autorelease
-(id)
autorelease
{
return
self;
}
至此我们的单例模式基本创建完毕,下面开始我们的测试吧;
在main函数中的代码如下:
//单例模式的测试
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);
运行结果如下:
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还是可以给该对象分配一个新对象的,上面是线程不安全的,下面是线程安全的:
+
(id)sharedSingleton
{
static
MySingleton
*sharedSingleton
= nil;
static
dispatch_once_t
onceToken;
dispatch_once(&onceToken,
^{
sharedSingleton
= [[self
alloc]
init];
});
return
sharedSingleton;
}
相关文章推荐
- 从零开始学Objective-C(01)选择Objective-C之路
- [转]ActionScript 3.0入门:Hello World、文件读写、数据存储(SharedObject)、与JS互调
- Objective-C 协议
- Objective-C_语言_NSDate(时间类型)和NSCalendar(日历)NSTimeZone(时区)
- Objective-C 编码建议(编程习惯,规范)
- com/opensymphony/xwork2/spring/SpringObjectFactory.java:220:-1问题出现的原因及解决办法
- 启动服务器时出现异常:com/opensymphony/xwork2/spring/SpringObjectFactory.java:209:-1 :
- Swift项目兼容Objective-C问题汇总
- 设备模型的基础---kobject,kset
- Objective-c NSRange用法及和NSString的关系
- POJ3241 Object Clustering 曼哈顿最小生成树
- html中object标签详解
- OBJECT和EMBED标签
- GsonWithoutObject 没有对象(脱离对象) 直接提取 ... gson json
- 冒泡排序的两个例子(objective-c)
- Objective-c语言_练习题3
- Objective-C中的内存管理
- Objective--C UISegmentedControl 交通灯
- Object-c学习笔记
- Objective--C Slider实现三原色之间颜色变化