iOS 细说单例
单例模式###
定义####
保证一个类仅有一个实例,并提供一个访问它的全局结点。当程序被杀死时,该实例对象被释放
好处####
实例控制:单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保对象都访问唯一实例。
灵活性:因为类控制了实例化过程,所以类可以灵活更改实例化过程
应用场景####
某个类经常被使用(节约系统资源)
定义工具类
共享数据
创建单例####
假如要给一个SYJCar的类创建单例,其.m文件的代码如下:
方法一 GCD方式创建单例#####
#import "SYJCar.h"
@interface SYJCar ()<NSCopying>
@end
@implementation SYJCar
static id _instance;//定义一个全局的static的实例
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
//dispatch_once保证程序在运行过程中只会被运行一次,从而保证了只会创建一个实例对象。
return _instance;
}
+(instancetype)sharedInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init];
});
return _instance;
}
-(id)copyWithZone:(NSZone *)zone
{
return _instance;
}
@end
方法二 互斥锁方式#####
#import "SYJCar.h"
@interface SYJCar ()<NSCopying>
@end
@implementation SYJCar
static id _instance;//定义一个全局的static的实例
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
@synchronized(self){
if(_instance == nil){
_instance = [super allocWithZone:zone];
}
}
return _instance;
}
+(instancetype)sharedInstance
{
//加锁
@synchronized (self) {
if(_instance == nil){
//保证只会创建一个实例对象
_instance = [[self alloc] init];
}
}
return _instance;
}
-(id)copyWithZone:(NSZone *)zone
{
return _instance;
}
@end
使用互斥锁会影响性能,所以最好还是使用GCD方式创建单例。
思考:如果我们需要在程序中创建多个单例,那么需要在每个类中都写上一次这段代码是不是太傻X了?我们可以使用宏来封装单例的创建,代码如下:
//.h文件使用
#define SYJSingletonH +(instancetype)sharedInstance;
//.m文件使用
#define SYJSingletonM \
static id _instance; \
+(instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
+(instancetype)sharedInstance \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
-(id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
}
演示####
viewController.h文件
viewController.m文件
结果显示,单例创建成功!