iOSの単例のいくつかの書き方

3331 ワード

1、GCDを使わない方式
static Manager *manager;

@implementation Manager

+(Manager *)defaultManager{

if(!manager)

manager=[[self allocWithZone:NULL] init];

return  manager;

}

@end

2、GCDを使う
#import "Manager.h"
@implementation Manager
+(Manager *)sharedManager{
  static dispatch_once_t predicate;
  static Manager * sharedManager;
  dispatch_once(&predicate, ^{
    sharedManager=[[Manager alloc] init];
  });
  return sharedManager;
}
@end
  :dispatch_once    ,                            !

//補足:Objective-CのAllocとAllocWithZone一、問題の起源
すべてはAppleの公式文書の中の単例(Singleton)に関するモデルコード:Creating aSingleton Instance.の主な論争は以下の部分に集中している.
static MyGizmoClass *sharedGizmoManager =nil; 
+(MyGizmoClass*)sharedManager 
{ 
if (sharedGizmoManager == nil){ 
sharedGizmoManager = [[super allocWithZone:NULL]init]; 
} 
return sharedGizmoManager; 
} 
+ (id)allocWithZone:(NSZone*)zone 
{ 
return [[self sharedManager]retain]; 
}
  :
sharedGizmoManager = [[super allocWithZone:NULL]init];

このセクションには、allocWithZoneではなく直接allocという別のバージョンがあります.sharedGizmoManager=[[super alloc]init];なぜallocWithZoneメソッドをカバーするのか、allocとallocWithZoneにはどのような違いがあるのかという議論が起きています.
二、allocWithZoneまず私达は知っていて、私达は単例类がただ1つの唯一の実例だけあることを保证する必要があって、ふだん私达は1つのオブジェクトを初期化する时、[[Class alloc]init]、実は2つの事をしました.allocはオブジェクトにメモリ領域を割り当て、initはオブジェクトの初期化であり、メンバー変数の初期値を設定するなどの作業を含む.オブジェクトに空間を割り当てるには、allocメソッドのほかに、allocWithZone.NSObjectというクラスの公式ドキュメントでは、allocWithZoneメソッドが紹介しています.このメソッドのパラメータは無視され、正しい方法はnilまたはNULLパラメータを渡すことです.この方法が存在するのは、歴史が残した原因だ.Do notoverride allocWithZone: to include any initialization code.Instead, class-specific versions of init… methods. This method exists for historical reasons; memory zones are nolonger used by Objective-C.ドキュメントには、memoryzoneはすでに廃棄されており、歴史的な理由だけでこのインタフェースが保持されていると記載されています.詳しい歴史的な理由は分かりませんが、後で紹介する内容は少し触れます.一方,allocメソッドを用いてクラスのインスタンスを初期化する場合,デフォルトではallocWithZoneメソッドが呼び出されることが実証されている.そこでallocWithZoneメソッドを上書きする理由は明らかである:単一クラスインスタンスの一意性を維持するためには、新しいインスタンスを生成するすべてのメソッドを上書きする必要があり、この単一クラスを初期化する際にallocWithZoneを歩かずに直接[[Classalloc]init]を実行する人がいれば、この単一インスタンスはもう単一のインスタンスではないので、このメソッドもブロックしなければならない.allocWithZoneの答えはここまでで解決したが、問題は尽きない.ここでもう一つの質問があります.
三、NSZone Appleの公式文書には簡単な言葉があり、NSZone Used to identify and managemmory zonesを引用する.
typedef struct _NSZoneNSZone; Availability Available in OS X v10.0 andlater. Declared In NSZone.h
NSZoneは、Appleがメモリを割り当てて解放するための方法であり、オブジェクトではなく、C構造を使用してオブジェクトのメモリ管理に関する情報を格納しています.基本的に開発者はこれを気にする必要はありません.cocoaApplicationはシステムのデフォルトのNSZoneを使用してアプリケーションのオブジェクトを管理します.では、いつ自分でコントロールするNSZoneがほしいですか?デフォルトのNSZoneで大量のオブジェクトが管理されている場合.この場合、大量のオブジェクトの解放はメモリの深刻な断片化を招く可能性があり、cocoa自体が最適化され、allocのたびにメモリの隙間を埋めようとしますが、そうすると時間のオーバーヘッドが大きくなります.したがって、自分でNSZoneを作成することができ、allocリクエストが大量にある場合、指定されたNSZoneにすべて移行し、時間のオーバーヘッドを大幅に削減することができます.また、NSZoneを使用すると、作成したzoneの中のものを一気に消去することができ、deallocオブジェクトを1つずつ削除するのに多くの時間を節約することができます.総じて言えば、大量のオブジェクトを作成する必要がある場合、NSZoneを使用すると時間を節約できますが、どのように使用するかを知っておく必要があります.Timothy氏はまた、NSZoneを使用できれば、複数のオブジェクトが同じ時間にallocを使用することで、ページングの使用を減らすことができ、同じ時間にdeallocを使用することでメモリの破片を減らすことができると述べた.Appleは後でこの方面で処理したに違いない.開発者には透明で、開発者が自分でする必要はない.
四、結論allocWithZoneはAppleに奨励されず、基本的にプログラマーも自分のzoneを管理する必要がないことが多い.もちろんもっと知っておくといいですね.
テキストリンク:http://www.cocoachina.com/bbs/read.php?tid=116873&fpage=33