過去一直背不下來單例如何寫,就是知道這麼回事,也知道通過宏來寫單例,但是一直記不住,今天就來記錄一下
- (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版本的單例,正常寫,沒研究過單例

