单例模式(singleton)

单例类: 如果一个类始终只能创建一个实例,则这个类就被称为单例类.

1.使用场景

    在某些时候,程序多次创建该类的对象没有任何意义,频繁创建对象,后手对象带来的系统开销会造成系统性能下降,此时程序需要保证该类只有一个实例.

2.实现

    1> 单例类可以同过 static 全局变量来实现,该变量用于保存已创建的 Singleton 对象,每次程序需要获取该实例时,先判断该全局变量是否为 nil,如果为 nil,就初始化一个并赋值给全局变量.

    2> 为了防止程序创建新的实例,需要重写一些方法:

    ① 全局变量初始化在第一次调用工厂方法时会在 ininWithZone: 中进行,其实 alloc 是设为 NULL的 zone 来调用 allocWithZone:,默认区域(zone)为新实例分配内存.

    ② 防止 copy 方法得到新的实例,需要重写 copyWithZone:方法

    ③ 因为全局变量不允许释放,所以和内存有关的 retain,release,autorelease,retainCount 方法均要重写.

例子:

Cat 类的声明

1 #import <Foundation/Foundation.h>
2 
3 @interface Cat : NSObject <NSCopying>
4 @property (assign,nonatomic) int age;
5 @property (strong,nonatomic) NSString *name;
6 // 获得全局实例的方法
7 + (id) getInstance;
8 @end

Cat 类的实现

 1 #import "Cat.h"
 2 // 创建一个全局变量,用来存放实例,初始化为 nil
 3 static id instance = nil;
 4 @implementation Cat
 5 // 实现工厂方法
 6 +(id)getInstance
 7 {
 8     // 如果实例变量为 nil,就实例化一个
 9     if (!instance) {
10         instance = [[super alloc] init];
11     }
12     return instance;
13 }
14 
15 // 防止 alloc 或者 new 来创建新实例
16 +(instancetype)allocWithZone:(struct _NSZone *)zone
17 {
18     if (instance == nil) {
19         instance = [[super allocWithZone:zone] init];
20     }
21     return instance;
22 }
23 
24 // 防止 copy 创建新实例
25 -(id)copyWithZone:(struct _NSZone *)zone
26 {
27   
28     return self;
29 }
30 
31 // 防止被 dealloc,此方法中返回最大值
32 - (NSUInteger)retainCount
33 {
34     return  NSUIntegerMax;
35 }
36 
37 // 防止引用计数器变化
38 -(instancetype)retain
39 {
40     return self;
41 }
42 
43 // 防止引用计数器发生变化
44 - (oneway void)release
45 {
46     
47 }
48 
49 // 防止引用计数器发生变化
50 - (instancetype)autorelease
51 {
52     return self;
53 }
54 
55 @end

主函数

 1 #import <Foundation/Foundation.h>
 2 #import "Cat.h"
 3 
 4 int main(int argc, const char * argv[]) {
 5     @autoreleasepool {
 6         Cat *cat1 = [[Cat alloc] init];
 7         Cat *cat2 = [[Cat alloc] init];
 8         Cat *cat3 = [[Cat alloc] init];
 9         Cat *cat4 = [cat3 copy];
10         
11         NSLog(@"%p",cat1);
12         NSLog(@"%p",cat2);
13         NSLog(@"%p",cat3);
14         NSLog(@"%p",cat4);
15         
16     }
17     return 0;
18 }

 

posted on 2015-02-04 09:39  sean.u  阅读(91)  评论(0)    收藏  举报