單例模式的作用是用來解決一個(gè)應(yīng)用中某個(gè)類只有唯一一個(gè)對(duì)象的問題。單例類在iOS開發(fā)中是非常重要的,在系統(tǒng)提供個(gè)類中,諸如:UIApplication類、NSUserDefaults類、NSNotificationCenter類、NSBundle類都是單例類。
1、單例類的使用
單例類在iOS的應(yīng)用開發(fā)中非常常見,有一些對(duì)象必須保證在整個(gè)應(yīng)用中只有一個(gè),當(dāng)在不同的位置需要使用單例類對(duì)象時(shí),能夠保證獲取的都是同一個(gè)對(duì)象。
例如,我們常見的QQ音樂里面,在每個(gè)節(jié)目下方都有一個(gè)當(dāng)前播放音樂的指示器,即便切換不同的界面,這個(gè)音樂播放指示器都是統(tǒng)一的,這個(gè)就是一個(gè)典型的單例類對(duì)象。


2、單例類的實(shí)現(xiàn)方式
單例類的實(shí)現(xiàn)原理就是要保證單例類對(duì)象的alloc+init操作,在應(yīng)用的整個(gè)生命周期過程中,只執(zhí)行一次。當(dāng)單例類對(duì)象被創(chuàng)建后,假如在其他多個(gè)地方需要使用該對(duì)象,則無需執(zhí)行alloc+init操作,而是直接返回已經(jīng)存在的對(duì)象即可。
在單例類的實(shí)現(xiàn)過程中,為了保證alloc+init只執(zhí)行一次,可以使用dispatch_once函數(shù),dispatch_once函數(shù)的作用就是在整個(gè)應(yīng)用生命周期中執(zhí)行一次代碼塊。
單例類的創(chuàng)建過程是完全一致的,因此,單例類的實(shí)現(xiàn)代碼只要直接復(fù)制/粘貼即可。通過下方的代碼,就能夠?qū)崿F(xiàn)如下功能:
創(chuàng)建一個(gè)單例類;
提供了一個(gè)類方法sharedInstance,通過該方法就能夠獲取到該單例類的對(duì)象;
提供了copy方法,調(diào)用copy方法時(shí),也是返回已經(jīng)存在的單例類對(duì)象;
(注意:由于ARC已經(jīng)成為主流,所以以下的單例類創(chuàng)建方法只考慮ARC)
.h文件
#import
@interfaceSingleton:NSObject
/**
*? 獲取單例類
*
*? @return 單例類對(duì)象
*/
+(instancetype)sharedInstance;
@end
.m文件
#import "Singleton.h"
@implementationSingleton
staticid _instance;
+(instancetype)sharedInstance
{
staticdispatch_once_tonceToken;
dispatch_once(&onceToken,^{
_instance=[[selfalloc]init];
});
return_instance;
}
+(id)allocWithZone:(struct_NSZone*)zone
{
staticdispatch_once_tonceToken;
dispatch_once(&onceToken,^{
_instance=[superallocWithZone:zone];
});
return_instance;
}
-(id)copyWithZone:(NSZone*)zone
{
return_instance;
}
@end
3、示例代碼
通過實(shí)際的代碼來驗(yàn)證以下單例類的實(shí)現(xiàn)效果。
創(chuàng)建三個(gè)自定義類:HCPerson、HCStudent、HCDog,其中:HCStudent是HCPerson的子類;
把HCPerson和HCDog定義為單例類,即拷貝上面代碼中@interface~@end以及@implementation~@end中的部分,分別到類的.h和.m文件中;
在main()函數(shù)中,實(shí)現(xiàn)如下代碼:
#import
#import "HCDog.h"
#import "HCPerson.h"
#import "HCStudent.h"
intmain(intargc,constchar*argv[]){
@autoreleasepool{
HCDog*dog1=[HCDogsharedInstance];
HCDog*dog2=[[HCDogalloc]init];
HCDog*dog3=[dog1 copy];
NSLog(@"dog1: %p, dog2: %p, dog3: %p",dog1,dog2,dog3);
HCPerson*person1=[[HCPersonalloc]init];
HCPerson*person2=[HCPersonsharedInstance];
HCStudent*student1=[[HCStudentalloc]init];
HCStudent*student2=[HCStudentsharedInstance];
NSLog(@"person1: %p, person2: %p, student1: %p, student2: %p",person1,person2,student1,student2);
}
return0;
}
運(yùn)行結(jié)果如下。我們可以看到,對(duì)于HCDog類,不論使用sharedInstance方法、alloc+init,還是copy方法,最后得到的都是同一個(gè)對(duì)象。對(duì)于HCPerson類來說,由于HCPerson類是單例類,因此,其子類也是單例類。
