objective-c 单例模式详解

来源:互联网 发布:torrent下载软件 编辑:程序博客网 时间:2024/05/29 17:44

最近在项目中需要用到单例模式(singleton),于是对谷歌了一些资料发现objective-c中的单例不是想象中的,apple官方文档建议并非如此,代码量是我好几倍,但是既然官方建议一定是有道理的,谷歌了写资料,多数都是建议这么使用,却没人对此做详解

因为没理解透,用着不踏实,所以决定做些调试,了解透彻!

按照一般的思路,如下

01static MyClass *class = nil;
02 
03@implementation MyClass
04 
05+(MyClass *)sharedMyClass{
06 
07    if (!class) {
08 
09       class = [[self alloc] init];
10 
11    }
12 
13    return class;
14 
15}
16 
17@end

调试发现

MyClass *A = [[MyClass allocinit];

NSLog(@"A:%@",A);

MyClass *B = [MyClass sharedMyClass];

NSLog(@"B:%@",B);

打印出的是

A:<MyClass: 0x6c72d30>

B:<MyClass: 0x6a87e60>

不是一个内存地址,也就是不是同一个实体

 

官方如下方式实现

01static MyClass *class = nil;
02 
03@implementation MyClass
04 
05+(MyClass *)sharedMyClass{
06    @synchronized (self){  //为了确保多线程情况下,仍然确保实体的唯一性
07        if (!class) {
08            [[self alloc] init]; //该方法会调用 allocWithZone
09        }
10    }
11    return class;
12}
13  
14 
15+(id)allocWithZone:(NSZone *)zone{
16    @synchronized (self){
17        if (!class) {
18            class = [super allocWithZone:zone]; //确保使用同一块内存地址
19            return class;
20        }
21    }
22    return nil;
23}
24 
25- (id)copyWithZone:(NSZone *)zone;{
26    return self; //确保copy对象也是唯一
27}
28 
29-(id)retain{
30    return self; //确保计数唯一
31}
32 
33- (unsigned)retainCount
34{
35   return UINT_MAX;  //装逼用的,这样打印出来的计数永远为-1
36}
37 
38- (id)autorelease
39{
40    return self;//确保计数唯一
41}
42 
43- (oneway void)release
44 
45{
46     //重写计数释放方法
47}
48 
49@end

 

再调试

MyClass *A = [[MyClassallocinit];

NSLog(@"A:%@",A);

MyClass *B = [MyClasssharedMyClass];

NSLog(@"B:%@",B);

MyClass *C = [A copy];

NSLog(@"C:%@",C);

 

打印出的是

A:<MyClass: 0x6a1e130>

B:<MyClass: 0x6a1e130>

C:<MyClass: 0x6a1e130>

都是指向同一块内存地址

答案已经出来了

apple建议的方式显然真正的确保了实体的唯一性

0 0
原创粉丝点击