objective-c 单例模式详解
2014-03-05 16:47
363 查看
最近在项目中需要用到单例模式(singleton),于是对谷歌了一些资料发现objective-c中的单例不是想象中的,apple官方文档建议并非如此,代码量是我好几倍,但是既然官方建议一定是有道理的,谷歌了写资料,多数都是建议这么使用,却没人对此做详解
因为没理解透,用着不踏实,所以决定做些调试,了解透彻!
按照一般的思路,如下
调试发现
MyClass*A=[[MyClassalloc]init];
NSLog(@"A:%@",A);
MyClass*B=[MyClasssharedMyClass];
NSLog(@"B:%@",B);
打印出的是
A:<MyClass:0x6c72d30>
B:<MyClass:0x6a87e60>
不是一个内存地址,也就是不是同一个实体
官方如下方式实现
再调试
MyClass*A=[[MyClassalloc]init];
NSLog(@"A:%@",A);
MyClass*B=[MyClasssharedMyClass];
NSLog(@"B:%@",B);
MyClass*C=[Acopy];
NSLog(@"C:%@",C);
打印出的是
A:<MyClass:0x6a1e130>
B:<MyClass:0x6a1e130>
C:<MyClass:0x6a1e130>
都是指向同一块内存地址
答案已经出来了
apple建议的方式显然真正的确保了实体的唯一性
因为没理解透,用着不踏实,所以决定做些调试,了解透彻!
按照一般的思路,如下
01 | static MyClass * class = nil; |
02 |
03 | @implementation MyClass |
04 |
05 | +(MyClass *)sharedMyClass{ |
06 |
07 | if (! class ) { |
08 |
09 | class = [[selfalloc]init]; |
10 |
11 | } |
12 |
13 | return class ; |
14 |
15 | } |
16 |
17 | @end |
MyClass*A=[[MyClassalloc]init];
NSLog(@"A:%@",A);
MyClass*B=[MyClasssharedMyClass];
NSLog(@"B:%@",B);
打印出的是
A:<MyClass:0x6c72d30>
B:<MyClass:0x6a87e60>
不是一个内存地址,也就是不是同一个实体
官方如下方式实现
01 | static 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 = //确保使用同一块内存地址 |
19 | return class ; |
20 | } |
21 | } |
22 | return nil; |
23 | } |
24 |
25 | - |
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 | - void )release |
44 |
45 | { |
46 | //重写计数释放方法 |
47 | } |
48 |
49 | @end |
MyClass*A=[[MyClassalloc]init];
NSLog(@"A:%@",A);
MyClass*B=[MyClasssharedMyClass];
NSLog(@"B:%@",B);
MyClass*C=[Acopy];
NSLog(@"C:%@",C);
打印出的是
A:<MyClass:0x6a1e130>
B:<MyClass:0x6a1e130>
C:<MyClass:0x6a1e130>
都是指向同一块内存地址
答案已经出来了
apple建议的方式显然真正的确保了实体的唯一性
相关文章推荐
- Objective-C——协议(Protocol)详解与代理(委托)设计模式
- 详解Objective-C编程中对设计模式中适的配器模式的使用
- objective-c 单例模式详解
- iOS的Objective-C的工厂设计模式详解
- JAVA设计模式之责任链模式详解
- STM32启动模式详解
- 单例模式 (懒汉式, 线程同步详解)
- C++/Debug模式查看EFL(标志寄存器)详解
- Java经典设计模式----五大创建型模式(附实例和详解)
- Java 设计模式之观察者模式的详解(行为模式)
- LVS-NAT和LVS-DR模式的实现详解
- spark之Standalone模式部署配置详解
- 单例模式三种模式,饿汉、饱汉、双重锁模式,实例及优劣详解
- Javascript 严格模式详解 (主要是function的this指针可以为空了!)
- Java 设计模式之访问者模式的详解(行为模式)
- Activity启动模式详解
- FTP主动模式和被动模式区别详解
- 单例模式详解
- 原型模式 详解
- Android MVP 模式 详解