?# 單例模式(面試必考)
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新聞熱點
疑難解答