單例模式是日常開(kāi)發(fā)工作中經(jīng)常會(huì)用到的一種設(shè)計(jì)模式躲撰。通過(guò)單例模式,可以保證程序中的一個(gè)類只有一個(gè)實(shí)例,從而方便對(duì)實(shí)例個(gè)數(shù)的控制以節(jié)省系統(tǒng)資源铣焊。因此,如果希望系統(tǒng)中的某個(gè)類只有一個(gè)實(shí)例罕伯,那單例模式是比較好的解決方案曲伊。
iOS開(kāi)發(fā)中,最常見(jiàn)的單例就是UIApplication。
簡(jiǎn)單介紹一下iOS中如何實(shí)現(xiàn)單例設(shè)計(jì)模式坟募。
在iOS中岛蚤,所有對(duì)象內(nèi)存空間的分配,最終都會(huì)調(diào)用 allocWithZone方法懈糯。也就是說(shuō)涤妒,當(dāng)我們寫(xiě)下如下代碼時(shí):
UIButton *btn = [[UIButton alloc] init];
實(shí)際上會(huì)調(diào)用 allocWithZone 方法。因此實(shí)現(xiàn)單例時(shí)赚哗,可以重寫(xiě) allocWithZone 方法她紫。
另外,GCD 提供了一個(gè)方法屿储,是專門(mén)用來(lái)創(chuàng)建單例的贿讹。提供的是 dispatch_once 宏」宦樱可以保證塊代碼中的指令只被執(zhí)行一次民褂,且多線程時(shí),是線程安全的疯潭,類只會(huì)被實(shí)例化一次赊堪。
重寫(xiě) allocWithZone 方法的代碼:
//重寫(xiě)allocWithZone方法實(shí)現(xiàn)單例
//GCD提供了一個(gè)方法來(lái)創(chuàng)建單例,該方法是線程安全的
+ (id)allocWithZone:(struct _NSZone *)zone
{
static Singleton *instance;
//dispatch_once是線程安全的袁勺,onceToken默認(rèn)為0
//且dispatch_once 可以保證塊代碼中的指令只被執(zhí)行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [super allocWithZone:zone];
});
return instance;
}
這樣雹食,再實(shí)例化類對(duì)象時(shí),實(shí)際上返回的是一個(gè)唯一對(duì)象期丰。
為了方便外界訪問(wèn)該實(shí)例群叶,可以實(shí)現(xiàn)一個(gè) shared***方法,返回該類的實(shí)例钝荡,代碼如下:
+ (instancetype)sharedSingleton
{
return [[self alloc] init];
}
驗(yàn)證代碼如下:
- (void)viewDidLoad {
[super viewDidLoad];
Singleton *single = [[Singleton alloc] init];
NSLog(@"single = %@",single);
Singleton *single2 = [Singleton sharedSingleton];
NSLog(@"single2 = %@",single2);
for(int i = 0; i < 10; ++i){
Singleton *testSingle = [[Singleton alloc] init];
NSLog(@"testSingle = %@",testSingle);
}
}
執(zhí)行結(jié)果:
可以看出街立,無(wú)論是多次 alloc ,還是 shared***埠通,得到的實(shí)例對(duì)象內(nèi)存地址都是一樣的赎离,說(shuō)明類的實(shí)例只有一個(gè)。