单例模式

单例模式

两种方式:

1.GCD方式

static id _instance;

+(instancetype)sharedPerson {
static dispatch_once_t onceToken;
// GCD dispatch_once, 本身是线程安全的,保证整个程序中只会执行一次
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init];
});
return _instance;
}

+(instancetype)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}

  • (id)copyWithZone:(NSZone *)zone {
    return _instance;
    }

  • (id)mutableCopyWithZone:(NSZone *)zone {
    return _instance;
    }

2.加锁方式:

static id _instance;
+(instancetype)allocWithZone:(struct _NSZone *)zone {
//方案: 加互斥锁,解决多线程访问安全问题
@synchronized(self){
if (_instance == nil) {
_instance = [super allocWithZone:zone];
}
}
return _instance;
}

+(instancetype)sharedCar {
@synchronized(self){
if (_instance == nil) {
_instance = [[self alloc] init];
}
}
return _instance;
}

  • (id)copyWithZone:(NSZone *)zone {
    return _instance;
    }

  • (id)mutableCopyWithZone:(NSZone *)zone {
    return _instance;
    }

可以采用禁用方法:
+(instancetype) new attribute((unavailable("OneTimeClass类只能初始化一次")));
-(instancetype) copy attribute((unavailable("OneTimeClass类只能初始化一次")));
-(instancetype) mutableCopy attribute((unavailable("OneTimeClass类只能初始化一次")));

  • (instancetype)init NS_UNAVAILABLE;
  • (instancetype)new NS_UNAVAILABLE;
  • (id)copy NS_UNAVAILABLE; // 没有遵循协议可以不写
  • (id)mutableCopy NS_UNAVAILABLE; // 没有遵循协议可以不写

优缺点:
优点:
(1)在整个程序中只会实例化一次,所以在程序如果出了问题,可以快速的定位问题所在;(2)由于在整个程序中只存在一个对象,节省了系统内存资源,提高了程序的运行效率;

缺点
(1)不能被继承,不能有子类;
(2)不易被重写或扩展(可以使用分类);
(3)同时,由于单例对象只要程序在运行中就会一直占用系统内存,该对象在闲置时并不能销毁,在闲置时也消耗了系统内存资源;

1:一个类只有一个对象,可能造成责任过重,在一定程度上违背了“单一职责原则”。
2:由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
3:滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。

你可能感兴趣的:(单例模式)