1、=====方法一 、废除 i艘绒庳焰nit / new 方法// .h文件中@interface UserManager : NSO芟鲠阻缒bject+ (UserManager *) sharedManager; //添加类方法// .m文件中第一步、废除原有 初始化方法 抛出异常- (instancetype) init { @throw [NSException exceptionWithName:@"" reason:@"不能调用init/new方法初始化CDUserManager对象" userInfo:nil];}第二步、方法重写 方法私有化- (instancetype) initPrivate { if (self = [super init]) { //设置属性 自定义 User *user = [[User alloc] init]; user.username = @"AAA"; user.password = @"123456"; user.email = @"[email protected]"; } return self;}第三步、创建单例对象(唯一的)+ (UserManager *) sharedManager{ static UserManager *manager = nil; //静态实例 并初始化 @synchronized (self) { // 同步保护 只允许一个线程进入 排队等候 if (!manager) { //如果为空 则新建 分配内存 初始化为私有 manager = [[self alloc] initPrivate]; } } return manager;//返回本类型 实例}
2、如果你用 init 或 new 来创建对象 就会抛出异常UserManager *uuu = [UserManager new];UserManager *uuu = [[UserManager alloc]init];
3、====方法二、可以 init / new 方法为了防止别人不小心利用alloc/init方式创建示例,也为了防止别人故意为之,我们要保证不管用什么方式创建都只能是同一个实例对象,这就得重写另一个方法,实现如下:可以将property的初始化或者默认值设置放到dispatch_once 的block内部写法一、static HLTestObject *instance = nil;+ (instancetype)sharedInstance { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // 设置属性 instance = [[[self class] alloc] init]; instance.height = 10; instance.object = [[NSObject alloc] init]; instance.arrayM = [[NSMutableArray alloc] init]; }); return instance;}//重写方法+ (instancetype)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [super allocWithZone:zone]; }); return instance;}写法二、static HLTestObject *instance = nil;+ (instancetype)sharedInstance { return [[self alloc] init];}- (instancetype)init { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [super init]; //== //设置属性 instance.height = 10; instance.object = [[NSObject alloc] init]; instance.arrayM = [[NSMutableArray alloc] init]; }); return instance;} //重写方法+ (instancetype)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [super allocWithZone:zone]; }); return instance;}//下面的方法 是为 copy mutableCopy 得到的对象也是唯一的//copy在底层 会调用copyWithZone:- (id)copyWithZone:(NSZone *)zone{ return instance;}+ (id)copyWithZone:(struct _NSZone *)zone{ return _instance;}+ (id)mutableCopyWithZone:(struct _NSZone *)zone{ return _instance;}- (id)mutableCopyWithZone:(NSZone *)zone{ return _instance;}可以用如下图的三种方法创建对象,得到的都是同一个
4、====dispatch_once 与@synchronized (self) 的比较使用dispatch_once可以简化代码并且彻底保证线程安全,开发者无需担心加锁或同步。此外,dispatch_once更高效,它没有使用重量级的同步机制,若是那样做的话,每次运行代码前都要获取锁。相反,此函数采用“原子访问”来查询标记,以判断其所对应的代码原来是否已经执行过
5、把单利抽出一个宏,以ARC为例