什么是單例,為什么要用單例?
1,單例模式:
確保某一個類只有一個實例。單例模式只會生成一個對象。內存空間永遠是一個,保證實體的唯一性。其他類可以通過全局的入口點對這個實例進行訪問。iOS sdk中也有許多類使用了單例模式,例如UIApplication:當程序啟動時,會調用UIApplicationMain方法,在該方法中,會實例化一個UIApplication對象,之后在程序中的任意地方調用shareApplication都將返回一個與當前應用程序相關的UIApplication實例。以及:[NSUserDefaluts standardUserDefaults]也是返回的一個單例對象,因為不能讓不同的ud對象去修改文件
2,單例模式的使用:
1,GCD:
+ (MyDataHelper *)shareMyDataHelper {
static MyDataHelper * myDataHelper = nil;
static dispatch_once_t takeOnce;
dispatch_once(&takeOnce,^{
myDataHelper = [self alloc]init];
} );
return myDataHelper;
}
利用GCD,可以保證初始化代碼只實現一次。前提是takeonce指針也必須是全局或者靜態變量。
因為static 修飾的成員變量只會初始化一次,如果不聲明為靜態變量,那么每次進來,都會重置變量為nil,那么就會重新創建對象。
2,重寫init,alloc方法,
1)先寫一個創建單例的方法
static MyDataHelper * myDataHelper = nil;
+ (MyDataHelper *)shareMyDataHelper {
@synchronized(self)
{
if (myDataHelper == nil)
{
[self alloc]init];
}
return myDataHelper;
}
+ (id)allocWithZone:(NSZone *)zone//在alloc分配內存空間的時候,是調用的allocWithZone分配空間
{
@synchronized(self){
if (myDataHelper == nil)
{
myDataHelper = [super allocWithZone:zone];
return myDataHelper;
}
}
return nil;
}
-(id)init {
@synchronized(self){
if( self ==[super init])
{
//初始化
}
return self;
}
- (id)copyWithZone:(NSZone *)zone{
return self;
}
以下是非ARC模式下需要添加的
-(unsigned)retainCount{
return 1// 永遠到返回1
}
- (oneway void)release {
釋放的時候什么也不做 }
(oneway 修飾符)表示此操作是單項的,這樣做意味著方法就算返回了什么,調用者也拿不到這個方法
如果需要實現單例的多態,就拿到單例對象之后,重新進行初始化就行。