import “Singleton.h”
//static修饰全局变量 对全局变量用static声明,则该变量的作用域只限于本文件模块(全局变量的作用域仅限于当前文件,即被声明的文件中)这里写代码片
static Singleton *_instance;
@implementation Singleton
+(instancetype)shareInstance{
//有时希望函数中的局部变量的值在函数调用结束后不消失而继续保留原值,即其占用的存储单元不释放,在下一次再调用的时候该变量已经有值。这时就应该指定该局部变量为静态变量,用关键字 static 进行声明。
//static修饰局部变量 让局部变量只初始化一次
//1.局部变量在程序中只有一份内存
//2.对局部变量用static声明,把它分配在静态存储区,该变量在整个程序执行期间不释放,其所分配的空间始终存在
//3.并不会改变局部变量的作用域,仅仅是改变了局部变量的生命周期(只到程序结束,这个局部变量才会销毁)
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc]init];
});
return _instance;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
return [Singleton shareInstance];
}
- (id)copyWithZone:(struct _NSZone *)zone {
return [Singleton shareInstance];
}
//单例模式实现方式是在类中编写名为sharedInstance的方法,该方法只会返回全类共用的单例实例,而不会在每次调用时都创建新的实例。
//使用同步块实现:
/*
+ (id)sharedInstance {
static ClassName *sharedInstance = nil;
@synchronized (self) {
if (!sharedInstance) {
sharedInstance = [[self alloc]init];
}
}
return sharedInstance;
}*/
/*
使用dispatch_once的注意事项:
此函数接收类型为dispatch_once_t的特殊参数,还有一个块参数。对于onceToken标记,该函数保证相关的块必定会执行,且执行一次。此操作完全是线程安全的。注意:对于只执行一次的块来说,对于传入函数的标记参数必须完全相同,因此,开发时需要将标记变量声明在static或global作用于中。
对于在dispatch_once中的创建的实例对象必须确保其只有一个,所以使用static修饰
上述两种实现单例的方法比较:使用dispatch_once可以简化代码且保证线程安全,开发者无需担心加锁或同步。所有问题都在GCD底层处理。此外,dispatch_once更高效。它没有使用重量级的同步机制。使用同步机制,每次运行代码都需要获取锁。dispatch_once采用“原子访问”来查询标记,判断代码是否执行过。
*/
@end