单例应用场合
在iOS的生命周期内,有时候我们只需要某个类的一个实例。
例如UIApplication, UIAccelerometer, NSUserDefaults, NSNotificationCenter, NSFileManger, NSBundle这些都是单例类的典型代表。
如何创建单例类
- 创建一个静态对象
- 提供一个静态方法
- 重写alloc方法
代码演示
我们首先创建一个类FileOperation, 继承自NSObject.
添加一个静态全局变量:
1 static FileOperation *instance = nil;
创建一个静态的方法
1 + (instancetype)sharedOperation{
//返回对象前需要判断,这个对象之前是否创建过,如果没有创建过,就需要创建一个对象,如果创建过,就把上一次的对象返回出去。这样可以保证创建的对象是唯一的对象 2 if (instance == nil) { 3 instance = [[super allocWithZone:NULL] init]; 4 } 5 return instance; 6 }
既然用户可能用静态方法创建对象,那么用户有没有可能使用allocWithZone创建对象呢?
我们在此又需要重写allocWithZone这个方法:
1 + (instancetype)allocWithZone:(struct _NSZone *)zone{ 2 if (instance == nil) { 3 instance = [[self alloc] init]; 4 } 5 return instance; 6 }
基本代码是:
1 #import "FileOperation.h" 2 3 //定义一个静态变量 4 //作用域:从定义开始到整个程序结束 5 static FileOperation *instance = nil; 6 7 @implementation FileOperation 8 9 + (instancetype)sharedOperation{ 10 if (instance == nil) { 11 instance = [[super allocWithZone:NULL] init]; 12 } 13 return instance; 14 } 15 16 17 18 + (instancetype)allocWithZone:(struct _NSZone *)zone{ 19 if (instance == nil) { 20 instance = [[self alloc] init]; 21 } 22 return instance; 23 } 24 25 26 @end
上述的代码只是在ARC中可以正确使用,如果实在MRC中,有retain,copy,release, autorelease,这些方法都会使得引用计数变化,我们都需要对这些方法重写。
1 -(id)retain 2 { 3 return instance; 4 } 5 -(void)release 6 { 7 8 } 9 -(id)autorelease 10 { 11 return instance; 12 } 13 -(id)copy 14 { 15 return instance; 16 } 17 -(NSUInteger)retainCount 18 { 19 return 1; 20 }
接下去检测一下生成的对象是不是相同的
1 FileOperation *f1 = [FileOperation sharedOperation]; 2 FileOperation *f2 = [FileOperation sharedOperation]; 3 FileOperation *f3 = [[FileOperation alloc] init]; 4 FileOperation *f4 = [[FileOperation alloc] init]; 5 6 NSLog(@"f1:%p", f1); 7 NSLog(@"f2:%p", f2); 8 NSLog(@"f3:%p", f3); 9 NSLog(@"f4:%p", f4);
打印出来的结果如下
所以是相同的对象!