探究Object-c中的單例模式中的allocWithZone做用的實踐

近由於在ios應用開發中,考慮到一些公共方法的封裝使用,就決定使用單例模式的寫法了。。不知道,Object-c中的單例模式的寫法是否和java中的寫法是否有所區別? 因而阿堂從網上一搜,發現「 Objective-C的singleton模式 」一文被不少人 轉載了,其主要內容以下
Apple官方建議
  因爲本身設計單態模式存在必定風險,主要是考慮到可能在多線程狀況下會出現的問題,所以蘋果官方建議使用如下方式來實現單態模式:
static MyGizmoClass *sharedGizmoManager = nil;
  + (MyGizmoClass*)sharedManager
  {
  @synchronized(self) {
  if (sharedGizmoManager == nil) {
  [[self alloc] init]; // assignment not done here
  }
  }
  return sharedGizmoManager;
  }
  + (id)allocWithZone:(NSZone *)zone
  {
  @synchronized(self) {
  if (sharedGizmoManager == nil) {
  sharedGizmoManager = [super allocWithZone:zone];
  return sharedGizmoManager; // assignment and return on first allocation
  }
  }
  return nil; //on subsequent allocation attempts return nil
  }
  - (id)copyWithZone:(NSZone *)zone
  {
  return self;
  }
  - (id)retain
  {
  return self;
  }
  - (unsigned)retainCount
  {
  return UINT_MAX; //denotes an object that cannot be released
  }
  - (void)release
  {
  //do nothing
  }
  - (id)autorelease
  {
  return self;
  }
按照我在java開發中的經驗,我通常會將其中的以下寫法
static MyGizmoClass *sharedGizmoManager = nil;
  + (MyGizmoClass*)sharedManager
  {
  @synchronized(self) {
  if (sharedGizmoManager == nil) {
  [[self alloc] init]; // assignment not done here
  }
  }
  return sharedGizmoManager;
  }
  + (id)allocWithZone:(NSZone *)zone
  {
  @synchronized(self) {
  if (sharedGizmoManager == nil) {
  sharedGizmoManager = [super allocWithZone:zone];
  return sharedGizmoManager; // assignment and return on first allocation
  }
  }
  return nil; //on subsequent allocation attempts return nil
  }
改爲
static MyGizmoClass *sharedGizmoManager = nil;
  + (MyGizmoClass*)sharedManager
  {
  @synchronized(self) {
  if (sharedGizmoManager == nil) {
  sharedGizmoManager = [[self alloc] init]; // assignment not done here
  }
  }
  return sharedGizmoManager;
  }
不懂這裏還要弄個(id)allocWithZone:(NSZone *)zone起啥子用?
可是轉念一想,既然Apple官方建議那樣作,確定是有它的做用的,因而阿堂決定寫個測試demo,一探明細!
測試類


 

調用 java

 

控制檯輸出結果 ios


至此終於真相大白了。。原來[[self alloc] init]; 調用時,會默認調用+ (id)allocWithZone:(NSZone *)zone方法的。。sharedGizmoManager 最終是在allocWithZone:(NSZone *)zone方法中完成了初始化操做。。 多線程

sharedGizmoManager = [super allocWithZone:zone]; 性能

阿堂再進一步查cocoa文檔,原來allocWithZone:(NSZone *)zone是在給對象sharedGizmoManager 分配內存空間了。其zone 能夠想象成一個內存池,alloc,allocWithZone或是dealloc這些操做,都是在這個內存池中操做的。cocoa老是會配置一個默認的NSZone,任何默認的內存操做都是在這個「zone」上操做的。默認的NSZone的缺陷在於,它是全局範圍的,時間一長,必然會致使內存的碎片化,若是你須要大量的alloc一些object,那麼性能就會受到一些影響。全部cocoa提供方法,你能夠本身生成一個NSZone(實際上就是我上面的demo那樣,重寫allocWithZone方法就好了),並將alloc, copy所有限制在這個」zone「以內。 測試

相關文章
相關標籤/搜索