单例类: 如果一个类始终只能创建一个实例,则这个类就被称为单例类.
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 }
浙公网安备 33010602011771号