0

私はObjectiveC(非ARC)でシングルトンを実装する方法を見つけました。

マット・ギャロウェイのシングルトン

// AppTools.h in my code

@interface AppTools : NSObject {

    NSString *className;
}

@property ( nonatomic, retain ) NSString *className;

+ ( id ) sharedInstance;

@end    // AppTools


// AppTools.m in my code

static AppTools *sharedAppToolsInstance = nil;

@implementation AppTools

@synthesize className;

- ( id ) init {

    self = [ super init ];
    if ( self ) {
        className = [ [ NSString alloc ] initWithString: @"AppTools" ];
    }
    return self;
}   // init

- ( void ) dealloc {

   // Should never be called, but just here for clarity really.
   [ className release ];
   [ super dealloc ];
}   // dealloc

+ ( id ) sharedInstance {

    @synchronized( self ) {
    if ( sharedAppToolsInstance == nil )
        sharedAppToolsInstance = [ [ super allocWithZone: NULL ] init ];
    }
    return sharedAppToolsInstance;
}   // sharedInstance

+ ( id ) allocWithZone: ( NSZone * )zone {

    return [ [ self sharedInstance ] retain ];
}   // allocWithZone:

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

    return self;
}   // copyWithZone:

- ( id ) retain {

    return self;
}   // retain

- ( unsigned int ) retainCount {

    return UINT_MAX;    // denotes an object that cannot be released
}   // retainCount

- ( oneway void ) release {

    // never release
}   // release

- ( id ) autorelease {

    return self;
}   // autorelease

sharedInstanceメソッドでallocWithZone:を操作する方法を知りたいのですが。この場合、allocWithZone:メソッドのレシーバーは「super」であり、「super」はNSObjectです。戻り値はNSObjectインスタンスですが、sharedInstanceに置き換えられます。

では、classNameのメモリルームはどこにありますか?コードのこの部分の操作方法がわかりません。

少し早いですがお礼を。

4

3 に答える 3

3

あなたが投稿したコードは、シングルトンを作成するには難しすぎると思います。

私のすべてのプロジェクトで、次のコードを使用してシングルトンを使用しています。これは非常にシンプルで、スレッドセーフで、完璧に動作します:

+ (CustomClass *)shared
{
    static CustomClass *singleton = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        singleton = [[CustomClass alloc] init];
    });
    return singleton;
}

ARC および非 ARC プロジェクトで使用できると思います。

更新: コメントで述べたように、実際には特定のクラスのインスタンスが複数作成される可能性があるためではshared objectありません。singletonしかし、それは十分に近いです。

私の意見では、あなたがオープン ソース コード/ライブラリを作成しておらず、他の誰もそれを使用しない場合は、共有オブジェクトを使用してそれらをシングルトンとして扱う方がはるかに簡単かもしれません。

于 2012-10-17T00:00:12.373 に答える
2

I use the same code as Nekto but singleton = [[CustomClass alloc] init]; should be singleton = [[self alloc] init];.

Imagine a subclass CustomSubclass. If you call

CustomSubclass *sharedObject = [CustomSubclass shared];

you will not get a CustomSubclass but a CustomClass.

于 2012-10-20T16:35:58.127 に答える
1

「className のメモリ ルームはどこですか?」と尋ねます。

allocほとんどのクラスはor自体を実装していませんallocWithZoneが、 から継承された実装に依存していNSObjectます。実装は、元の呼び出しクラスNSObjectオブジェクトを割り当てます。

したがって、あなたの例でAppToolsは overrideを実行しallocWithZone、この実装はへNSObjectallocWithZone呼び出しを介して を呼び出しsuperNSObjectのメソッドは実際の割り当てを実行し、タイプのオブジェクトを返しますAppTools

[注:NSObjectの実装がどの種類のオブジェクトを割り当てるかをどのように認識しているか疑問に思っている場合、これは簡単です。継承されたメソッドを呼び出してもself、メソッドへの引数は変更されませんalloc。/allocWithZoneはクラス メソッドであり、selfクラス メソッドの引数は、クラス オブジェクト (クラスのインスタンス オブジェクトではなく) 自体。]

于 2012-10-17T02:07:54.080 に答える