“单例模式”是我们在iOS中最常使用的设计模式之一。例如,UIApplication类有一个方法叫sharedApplication,从任何地方调用这个方法,都将返回与当前正在运行的应用程序相关联的UIApplication实例。除了这个,NSNotificationCenter(消息中心) 、NSFileManager(文件管理) 、 NSUserDefaults(持久化存储数据) 、NSURLCache(请求缓存)、NSHTTPCookieStorage(应用程序cookies池)都是系统单例;
单例类保证了应用程序的生命周期中有且仅有一个该类的实例对象,而且易于外界访问。
单例模式的优点:
1.实例控制:Singleton 会阻止其他对象实例化其自己的 Singleton 对象的副本,从而确保所有对象都访问唯一实例。
2.灵活性:因为类控制了实例化过程,所以类可以更加灵活修改实例化过程。
单例类的实现方法:
(1).通过加线程锁进行实现:
比如创建了一个DBManager的类
+(DBManager *)sharedManager; (.h文件中)
.m文件中的实现:
+(DBManager *)sharedManager{
Static DBManager *manager = nil;
@synchronized(self){
if(manager == nil){
manager = [[DBManager alloc]init];
}
}
return manager;
}
(2).通过GCD实现单例方法:
+(DBManager *)sharedManager; (.h文件中)
适当实现copyWithZone,release和autorelease。
- (id)init;
{
@synchronized(self) {
if (self = [super init]){
return self;
}
return nil;
}
}
.m文件中的实现:
+(DBManager *)sharedManager{
Static DBManager *manager = nil;
static dispatch_once_t token;
dispatch_once(&token,^{
dispatch_once(&token,^{
if(manager == nil){
manager = [[DBManager alloc]init];
}
} );
return manager;
}
重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实力的时候不产生一个新实例,
+(id)allocWithZone:(NSZone *)zone{
@synchronized(self){
if (!manager) {
manager = [super allocWithZone:zone]; //确保使用同一块内存地址
return manager;
}
return nil;
}
}
+(id)allocWithZone:(NSZone *)zone{
@synchronized(self){
if (!manager) {
manager = [super allocWithZone:zone]; //确保使用同一块内存地址
return manager;
}
return nil;
}
}
适当实现copyWithZone,release和autorelease。
- (id)init;
{
@synchronized(self) {
if (self = [super init]){
return self;
}
return nil;
}
}
swift
final class ConfigReadJsonHelper: NSObject {
static let shared = ConfigReadJsonHelper()
private override init() {
}
}
but--but--but--but--but--but--but--but--but--but--
单例的缺点:
1单例一旦创建,对象指针保存在静态区,单例对象在堆中分配的内存空间只有等程序结束才能释放,所以过多的单例会增大内存的小号。如果不是应用程序的生命周期短,就不应该使用单例。网络封装的AFN等,一般是伴随着程序的出生和结束的,所以一般使用单例模式来封装网络请求。程序设计的模式有很多,要灵活应用。
2 不好扩展