3

iPhone アプリでデータを追跡するためにシングルトン クラスを作成しました。シングルトンは一度だけインスタンス化する必要があることは知っていますが、インスタンス化するのに最適な場所はどこですか? これは appDelegate で行う必要がありますか? 配列にアクセスできるように、多数のクラスからこのシングルトン (NSMutableArray を含む) を呼び出せるようにしたいと考えています。

これが私が書いた私のクラスです:

#import "WorkoutManager.h"

static WorkoutManager *workoutManagerInstance;

@implementation WorkoutManager
@synthesize workouts;

+(WorkoutManager*)sharedInstance {
    if(!workoutManagerInstance) {
        workoutManagerInstance = [[WorkoutManager alloc] init];
    }
    return workoutManagerInstance;
}

-(id)init {
    self = [super init];
    if (self) {
        workouts = [[NSMutableArray alloc] init];
    }
    return self;
}

@end
4

5 に答える 5

6

ほとんどの場合、シングルトンのポイントは、誰が最初にインスタンス化したかを気にしないことです。最初に呼び出した人が[Something sharedSomething]作成者になります。「 ARC と互換性のある Objective-C シングルトンを実装するにはどうすればよいですか? 」 で指定されたパターンを使用したい場合、シングルトンが 1 回だけ作成されるようになります。

于 2012-04-11T00:51:21.433 に答える
2

通常、シングルトンは遅延してインスタンス化されます。最初にアクセスされると、インスタンスが作成され、アクセス メソッドから返されます。アクセス メソッドへの後続の呼び出しは、既に作成されたインスタンスを単に返します。

標準的なパターンは次のとおりです。 1. ロックを取得するか、次のスレッドセーフを作成します (つまり、dispatch_once())。2. 単一のインスタンスがまだ作成されているかどうかを確認します。3. ない場合は、作成します。4. ロックを解除します (該当する場合)。5. インスタンスを返します。

何らかの理由で必要な場合は、インスタンスを先に作成することができます。クラス メソッド+loadは、クラスがランタイムに追加されたときにランタイムによって送信されます。これは、アプリの実行の非常に早い段階です。(+initializeこれも候補のようです -- クラスが最初の (その他の) メッセージを受信する直前にランタイムによって送信されます ( も除く+load) -- しかし、直前に送信されるため、実際には何も得られません。あなたが送信しますsharedInstance。)

ObjC には実装されていないと文書化されていますが、 gcc__constructor__ 関数属性も (clang で) 機能します。この属性を持つ関数main()は、入る前に呼び出されます。ただし、このオプションのメモリ管理への影響についてはよくわかりません。ランタイムはすべてセットアップされているはずですが、自動解放プールはまだ配置されていません。

于 2012-04-11T00:51:51.947 に答える
1

これはおそらく最も簡単なアプローチです。

static MyClass* theInstance = nil;

+ (MyClass*) sharedInstance {
    @synchronized(self) {
        if (! theInstance) {
            theInstance = [[MyClass alloc] init];
        }
    }

    return theInstance;
}

...シングルトンにアクセスしたい場所では[MyClass sharedInstance]、インスタンスへの参照を取得するだけです。

allocこれは、人が手動で呼び出したりinit、シングルトン クラスで追加のインスタンスを作成したりするのを防ぐものではないことに注意してください。これを行う必要がある場合は、上記と同様の方法で実装して、およびinitを使用して追加のインスタンスが作成/返されるのを防ぐことができます。 allocinit

ただし、実際には、シングルトン クラスが最も一般的にこのsharedInstanceアプローチを使用します (場合によっては、 のように命名に多少の違いがあり[UIApplication sharedApplication]ます)。

于 2012-04-11T00:51:20.180 に答える
0

通常、シングルトン クラスは、最初にアクセスされたときにインスタンス化されます。

static SomeClass *_instance = nil;

+ (SomeClass *) instance {
    @synchronized(self) {
        if (!_instance)
            _instance = [[self alloc] init];
    }
    return _instance;
}
于 2012-04-11T00:54:11.207 に答える
0

このコードを使用して、シングルトンをインスタンス化しています。GCD が同期を処理します

+ (SingletonClass *)sharedInstance {
  static SingletonClass *sharedInstance;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [[SingletonClass alloc] init];
    sharedInstance.property = [Property new];
  });
  return sharedInstance;
}
于 2012-04-11T01:03:30.677 に答える