单例模式的作用
- 可以保证程序运行过程中,一个类只有一个实例,而且该实例易于供外界访问
- 节约系统资源
单例模式使用场合
- 在整个应用程序中,共享一份资源(这份资源只需要创建和初始化一次)
实现单例模式的方式
iOS中有两种实现单例模式的方式,一种是使用GCD,一种是不使用GCD
使用GCD实现单例模式代码
- .h文件
#import <Foundation/Foundation.h>
@interface LMHPerson : NSObject
//单例方法
+(instancetype)sharedPerson;
@end
- .m文件
#import "LMHPerson.h"
static LMHPerson * _person; // 单例(全局变量)
@implementation LMHPerson
/**
* 单例方法
*/
+(instancetype)sharedPerson{
// 确保只进行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [[self alloc]init];
});
return _person;
}
// alloc 会调用allocWithZone方法
+(instancetype)allocWithZone:(struct _NSZone *)zone{
// 确保只进行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [super allocWithZone:zone];
});
return _person;
}
//copy在底层 会调用copyWithZone方法
+ (id)copyWithZone:(NSZone *)zone{
return _person;
}
- 测试&打印
LMHPerson * person1 = [[LMHPerson alloc]init];
LMHPerson * person2 = [LMHPerson sharedPerson];
NSLog(@"%p %p", person1, person2);
可以看到,两个对象的内存地址都是一样的
不使用GCD实现单例模式代码
- .h文件
#import <Foundation/Foundation.h>
@interface LMHCat : NSObject
// 单例方法
+(instancetype)sharedCat;
@end
- .m文件
#import "LMHCat.h"
static LMHCat *_cat; // 单利(全局变量)
@implementation LMHCat
/**
* 单例方法
*/
+(instancetype)sharedCat{
@synchronized (self) { // 确保多线程情况下,仍然确保实体的唯一性
if (!_cat) {
_cat = [[LMHCat alloc]init];
}
}
return _cat;
}
// alloc 会调用allocWithZone方法
+(instancetype)allocWithZone:(struct _NSZone *)zone{
@synchronized (self) {
if (!_cat) {
_cat = [super allocWithZone:zone]; // 确保使用同一块内存地址
return _cat;
}
}
return nil;
}
//copy在底层 会调用copyWithZone方法
+ (id)copyWithZone:(NSZone *)zone{
return _cat;
}
- 测试&打印
LMHCat * cat1 = [[LMHCat alloc]init];
LMHCat * cat2 = [LMHCat sharedCat];
NSLog(@"%p %p", cat1, cat2);
在不使用CGD实现单例模式的时候,用到了synchronized(互斥锁),用来确保线程安全,确保对象得唯一性,封锁用户通过alloc和init以及copy来构造对象的路劲。