單例模式的作用是用來解決一個應用中某個類只有唯一一個對象的問題。單例類在iOS開發中是非常重要的,在系統提供個類中,諸如:UIApplication類、NSUserDefaults類、NSNotificationCenter類、NSBundle類都是單例類。
1、單例類的使用
單例類在iOS的應用開發中非常常見,有一些對象必須保證在整個應用中只有一個,當在不同的位置需要使用單例類對象時,能夠保證獲取的都是同一個對象。
例如,我們常見的QQ音樂里面,在每個節目下方都有一個當前播放音樂的指示器,即便切換不同的界面,這個音樂播放指示器都是統一的,這個就是一個典型的單例類對象。
2、單例類的實現方式
單例類的實現原理就是要保證單例類對象的alloc+init操作,在應用的整個生命周期過程中,只執行一次。當單例類對象被創建后,假如在其他多個地方需要使用該對象,則無需執行alloc+init操作,而是直接返回已經存在的對象即可。
在單例類的實現過程中,為了保證alloc+init只執行一次,可以使用dispatch_once函數,dispatch_once函數的作用就是在整個應用生命周期中執行一次代碼塊。
單例類的創建過程是完全一致的,因此,單例類的實現代碼只要直接復制/粘貼即可。通過下方的代碼,就能夠實現如下功能:
創建一個單例類;
提供了一個類方法sharedInstance,通過該方法就能夠獲取到該單例類的對象;
提供了copy方法,調用copy方法時,也是返回已經存在的單例類對象;
(注意:由于ARC已經成為主流,所以以下的單例類創建方法只考慮ARC)
.h文件
#import
@interfaceSingleton:NSObject
/**
*? 獲取單例類
*
*? @return 單例類對象
*/
+(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、示例代碼
通過實際的代碼來驗證以下單例類的實現效果。
創建三個自定義類:HCPerson、HCStudent、HCDog,其中:HCStudent是HCPerson的子類;
把HCPerson和HCDog定義為單例類,即拷貝上面代碼中@interface~@end以及@implementation~@end中的部分,分別到類的.h和.m文件中;
在main()函數中,實現如下代碼:
#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;
}
運行結果如下。我們可以看到,對于HCDog類,不論使用sharedInstance方法、alloc+init,還是copy方法,最后得到的都是同一個對象。對于HCPerson類來說,由于HCPerson類是單例類,因此,其子類也是單例類。