OC怎麼正確的寫單例
阿新 • • 發佈:2019-02-12
今天偶然看到一篇文章,有所感觸,這才發現寫了好久的單例竟然並沒有寫正確,研究了一下,總結如下:
@interface MySingle() <NSCopying, NSMutableCopying> @end @implementation MySingle + (instancetype)sharedInstance { static MySingle *single = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"dispatch_once"); single = [[super allocWithZone:NULL] init]; // 下面程式碼進行當前類的初始化操作 [single initSelf]; }); NSLog(@"shared called"); return single; } // 初始化程式碼 - (void)initSelf { self.myName = @"OK"; } // 不能使用下面這個類進行初始化,否則會陷入死迴圈,或會使用得外部呼叫[[xx alloc] init] 會再次觸發這個方法 //- (instancetype)init { // NSLog(@"init called"); // _myName = @"This is it."; // return self; //} + (instancetype)allocWithZone:(struct _NSZone *)zone { NSLog(@"allocWithZone"); return [MySingle sharedInstance]; } - (instancetype)copyWithZone:(NSZone *)zone { NSLog(@"copyWithZone"); return self; } - (instancetype)mutableCopyWithZone:(NSZone *)zone { NSLog(@"mutableCopyWithZone"); return self; } @end
使用時,下面幾種方式都能訪問到唯一的單例物件,且初始化方法也只會被呼叫一次,完美,收工。
MySingle *allIN = [[MySingle alloc] init]; NSLog(@"init:%@, name=%@", allIN, allIN.myName); MySingle *the = [MySingle sharedInstance]; MySingle *copyIt = [the copy]; NSLog(@"c:%@, name=%@", copyIt, copyIt.myName); NSLog(@"m:%@", [the mutableCopy]);
需要注意的是, 上面sharedInstance中寫初始化時使用的是super allocWithZone, 這裡不能寫成self allocWithZone,否則會引發迴圈。