天天看點

iOS單例

最近在面試,有些總是會被問到,突然覺得自己雖然做了有一年多的iOS,也自己開發過幾款應用,但是有些基礎終究感覺自己狠模糊。

從現在起開始看中基礎,理論。

被問到的兩個比較多的問題, 單例以及什麼是KVO和KVC。

首先說單例模式。

單例的概念(Singleton):建立某類對象時,無論建立多少次該類對象隻有一份在記憶體中,通俗的将就是隻存在這個類的一個勢力對象。

在iOS中,有兩種單例實作模式,以下為例子。

1.使用 static 管理

@interface Singleton:NSObject

@end

@implement

static Singleton*sharedSingleton= nil;

+(Singleton*) sharedInstance{ 

  @synchronized(self)

  {     

     if (sharedSingleton== nil)

     {          

        sharedSingleton= [[Singleton alloc] init];       

     }   

  }

  return sharedSingleton; 

}

+(id) allocWithZone:(NSZone *)zone

{   

   @synchronized(self)

   {       

      if (sharedSingleton== nil)

     {   

        sharedSingleton= [super allocWithZone:zone];     

         returnsharedSingleton;      

     }

   }   

   return nil; 

- (id)copyWithZone:(NSZone *)zone{

return self;

-(id)retain{

- (void)release{

//do nothing

-(id)autorelease{

使用synchronized()可以防止多個線程同時執行該段代碼(線程鎖)

NSZone: 簡單來說可以把它想象成一個記憶體池,alloc或者dealloc這些操作都是在這個記憶體池中操作的,cocoa總是會配置設定一個預設的NSZone,任何 預設記憶體操作都是在這個zone上進行的,使用預設zone存在缺陷,因為他是全局範圍的,頻繁使用會導緻記憶體的碎片化,尤其是大量的alloc和 dealloc的時候,性能上會受到一定影響。因為你可以自己生成一個zone并将alloc,copy這些限制在這個zone中。

第二種是使用 GCD,不用synchronized,比較官方的例子

static dispatch_once_t onceToken;

dispatch_once(&onceToken,^{

sharedSingleton = [super allocWithZone:nil] init];

return instance;

+(id) allocWithZone:(NSZone*)zone {return[self sharedInstance];}      

以下是蘋果官方的例子。

static MyGizmoClass *sharedGizmoManager = nil;      
+ (MyGizmoClass*)sharedManager      
{      
if (sharedGizmoManager == nil) {      
sharedGizmoManager = [[super allocWithZone:NULL] init];      
}      
return sharedGizmoManager;      
}      
+ (id)allocWithZone:(NSZone *)zone      
{      
return [[self sharedManager] retain];      
}      
- (id)copyWithZone:(NSZone *)zone      
{      
return self;      
}      
- (id)retain      
{      
return self;      
}      
- (NSUInteger)retainCount      
{      
return NSUIntegerMax;  //denotes an object that cannot be released      
}      
- (void)release      
{      
//do nothing      
}      
- (id)autorelease      
{      
return self;      
}      

如果人家讓你寫單例,你能夠準确無誤的寫出單例,肯定會成功率比較高。加油