過去一直背不下來單例如何寫,就是知道這麼回事,也知道通過宏來寫單例,但是一直記不住,今天就來記錄一下
- (void)viewDidLoad { [super viewDidLoad]; SIPerson *person = [[SIPerson alloc] init]; NSLog(@"%@",person); SIPerson *person1 = [[SIPerson alloc] init]; NSLog(@"%@",person1); }
創建person,打印,實際上是2個對象。沒毛病.
創建方法
#import "SIPerson.h" static SIPerson *instance_ = nil; @implementation SIPerson ///方法1,快速創建對象 + (instancetype)sharedInstance{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance_ = [[self alloc] init]; }); return instance_; } ///方法2.這個方法一定要有,就是alloc] init]方法,一定會調用這個方法 + (instancetype)allocWithZone:(struct _NSZone *)zone{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance_ = [super allocWithZone:zone]; }); return instance_; } @end //此處還應該有一個+ copy方法,因為可能是copy,那麼有可能是生成新的方法
方法12都要實現,才能是單例。假如方法2沒有實現,通過
sharedInstance
實現的確實是一個單例,但是通過alloc] init]
有生成了另一個對象
2016-09-17 14:17:45.086 SharedInstance[9158:611161] 2016-09-17 14:17:45.087 SharedInstance[9158:611161]
如果你的對象將來可能還要調用
copy
(應該聲明協議),那麼你應該還要實現一個方法
- (id)copyWithZone:(NSZone *)zone{ return instance_; }
copy的時候,一般是生成了一個新的對象,所以不是單例了,但是用的時候比較少,不是特別需要的,可以不實現這個方法,為毛要這樣去寫?因為他是對象方法,
instance_
裡面有值
[super viewDidLoad]; SIPerson *person = [SIPerson sharedInstance]; NSLog(@"%@",person); SIPerson *person1 = [[SIPerson alloc] init]; NSLog(@"%@",person1); SIPerson *person2 = [person1 copy]; NSLog(@"%@",person2);
結果如下
2016-09-17 14:24:10.555 SharedInstance[9199:615987] 2016-09-17 14:24:10.555 SharedInstance[9199:615987] 2016-09-17 14:24:10.556 SharedInstance[9199:615987]
/** * 在.h文件中定義的宏,arc * * SISingletonH(name) 這個是宏 * + (instancetype)shared##name;這個是被代替的方法, ##代表著shared+name 高度定制化 * 在外邊我們使用 “SISingletonH(gege)” 那麼在.h文件中,定義了一個方法"+ (instancetype)sharedgege",所以,第一個字母要大寫 * * @return 一個搞定好的方法名 */ #define SISingletonH(name) + (instancetype)shared##name; /** * 在.m文件中處理好的宏 arc * * SISingletonM(name) 這個是宏,因為是多行的東西,所以每行後面都有一個"\",最後一行除外, * 之所以還要傳遞一個“name”,是因為有個方法要命名"+ (instancetype)shared##name" * @return 單利 */ #define SISingletonM(name) \ static SIPerson *instance_ = nil;\ + (instancetype)shared##name{\ static dispatch_once_t onceToken;\ 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_;\ }
實際使用
//.h文件SISingletonH(Default)
//.m文件SISingletonM(Default)
都是一句話,都沒有符號(定義的時候就給了符號),就這麼簡單
在實際使用的時候
[super viewDidLoad]; SIPerson *person = [SIPerson sharedDefault]; NSLog(@"%@",person); SIPerson *person1 = [[SIPerson alloc] init]; NSLog(@"%@",person1); SIPerson *person2 = [person1 copy]; NSLog(@"%@",person2); //打印結果 2016-09-17 14:56:39.508 SharedInstance[9292:633076] 2016-09-17 14:56:39.508 SharedInstance[9292:633076] 2016-09-17 14:56:39.508 SharedInstance[9292:633076]
拿來就可以使用的文件地址
簡單說一下如何定義swift版本的單例,正常寫,沒研究過單例