# 单例模式(面试必考)
1.在.m中保留一个全局的static的实例
static id _instance;
2.重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全)
+ (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:(struct _NSZone *)zone{ return _instance;}
static id _instance;+ (instancetype)allocWithZone:(struct _NSZone *)zone{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[super allocWithZone:zone] init]; // 记住这儿是super,不能用self }); return _instance;}+ (instancetype)sharedPerson{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; }); return _instance;}// copyWithZone方法的前提是必须先有一个对象- (id)copyWithZone:(NSZone *)zone{ return _instance;}
在实际开发中,一个应用程序可能有多个对象是单例对象,此时我们应该把单例抽成一个宏放在一个单独的.h文件中
,千万不能用继承
/
表示此行跟下面一行是一起的##
表示后面是参数// .h文件中的声明#define SLInstanceH(name) + (instancetype)shared##name;// .m文件的实现#define SLInstanceM(name) static id _instance; //+ (instancetype)allocWithZone:(struct _NSZone *)zone/{/ static dispatch_once_t onceToken;/ dispatch_once(&onceToken, ^{/ _instance = [[super allocWithZone:zone] init];/ });/ return _instance;/}//+ (instancetype)shared##name/{/ static dispatch_once_t onceToken;/ dispatch_once(&onceToken, ^{/ _instance = [[self alloc] init];/ });/ return _instance;/}//- (id)copyWithZone:(NSZone *)zone/{/ return _instance;/}
#import <Foundation/Foundation.h>#import "SLSharedInstance.h" // 导入,定义了宏的.h文件@interface SLPerson : NSObject<NSCopying>SLInstanceH(Person) // 传入单例的对象@end
#import "SLPerson.h"@implementation SLPersonSLInstanceM(Person)@end
#import "SLPerson.h"@implementation SLPersonstatic id _instance;+ (instancetype)allocWithZone:(struct _NSZone *)zone{ @synchronized(self){ // 一定要加互斥锁,不然会有线程安全问题 if (_instance == nil) { _instance = [[super allocWithZone:zone] init]; } } return _instance;}+ (instancetype)sharedPerson{ @synchronized(self){ if (_instance == nil) { _instance = [[self alloc] init]; } } return _instance;}// 要有对象才能进行copy- (id)copyWithZone:(NSZone *)zone{ return _instance;}@end
新闻热点
疑难解答