天天看點

Objective-C程式設計之道iOS設計模式單例解析(1)

此書中第85頁有如下一段話:

The alloc call is forwarded to super, which means NSObject will take care of the object allocation. If we subclass Singleton without any modification, the returned instance is always Singleton. Because Singleton overrides all the instantiation-related methods, it is quite tricky to subclass it.

起初我不了解一個問題,我的測試以下兩個方法建立子類執行個體,結果均運作良好。比如SingletonSon:Singleton,子類不做任何修改,當調用[SingletonSon sharedInstance]或[SingletonSon alloc]時傳回的執行個體是SingletonSon而不是Singleton。這與原文說法相反,原文說,如果不做修改的子類化Singleton,傳回的執行個體總是Singleton。

+(Singleton *) sharedInstance
{
   if(sharedSingleton==nil)
 {
    sharedSingleton=[[super allocWithZone:NULL] init];
 }
 return sharedSingleton;
}
           
+(Singleton *) sharedInstance
{
  if(sharedSingleton==nil)
  {
    sharedSingleton=[NSAllocateObject([self class],0,NULL) init];
  }
   return sharedSingleton;
}
           

這裡我忽略一個問題,即我們在Singleton.m檔案定義了一個static  Singleton* sharedSingleton類變量。這個變量隻有一份,父類與其子類共享,初始值為nil,是以如果先調用[Singleton sharedInstance],使sharedSingleton指向了Singleton類的執行個體對象,那麼之後調用[SingletonSon sharedInstance]或[SingletonSon alloc],傳回值将總是sharedSingleton所指向的Singleton類的執行個體對象。[SingletonSon alloc]也無法建立SingletonSon對象,它不會調用NSObject的alloc方法而是調用Singleton的alloc方法,因為其父類Singleton重寫執行個體化相關的方法,而此方法将直接傳回sharedSingleton所指向的值。

+(id) allocWithZone:(NSZone *)zone //Singleton重寫了執行個體化相關方法
{
  return [[self sharedInstance] retain];
}
           

是以要子類化Singleton,并希望處理好子類和父類的執行個體化問題,需要采用第二種方式。

@implementation SingletonSon
static Singleton *shareSingleton=nil; //向上轉型,重定義自己的sharedsingleton類變量,不與父類共享。
+(SingletonSon *) shareInstance
{
  if(sharedSingleton==nil)
    {
     //不調用父類alloc方法,在此調用父類alloc方法可能回調此方法,進而産生死循環,我們直接建立對象。
     sharedSingleton=[NSAllocateObject(self class),0,NULL) init];
    }
}// 子類可以重寫一下retain copy release autorelease進行合适的記憶體管理。
@end
           

我是小強,請多多指教。