16

通常のパターンを使用してシングルトン オブジェクトを実装しました。私の質問は: このオブジェクトを nil に戻して、後で [MySingleton sharedInstance] を呼び出したときにオブジェクトが再初期化されるようにすることは可能ですか?

// Get the shared instance and create it if necessary.
+ (MySingleton *)sharedInstance {

    static dispatch_once_t pred;
    static MySingleton *shared = nil;
    dispatch_once(&pred, ^{
        shared = [[MySingleton alloc] init];
    });
    return shared;
}

// We can still have a regular init method, that will get called the first time the     Singleton is used.
- (id)init 
{
    self = [super init];

    if (self) {
    // Work your initialising magic here as you normally would

    }
    return self;
}

私の推測では

MySingleton *shared = [MySingleton sharedInstance];
shared = nil;

ローカル ポインタsharedを に設定するだけnilです。結局のところ、sharedとして宣言されていstaticます。

4

3 に答える 3

44

ローカル参照に関するあなたの仮定は正しいです。シングルトンには影響しません。

シングルトンを再初期化できるようにするには、静的変数をメソッドから移動する必要があるため、クラス全体からアクセスできます。

static MySingleton *sharedInstance = nil;
// Get the shared instance and create it if necessary.
+ (MySingleton *)sharedInstance {
    if (sharedInstance == nil) {
        sharedInstance = [[MySingleton alloc] init];
    }
    return sharedInstance;
}

+ (void)resetSharedInstance {
    sharedInstance = nil;
}

dispatch_onceシングルトンは明らかに複数回作成する必要があるため、もう使用できないことに注意してください。このシングルトンを UI からのみ呼び出す場合 (つまり、メイン スレッドからのみ呼び出す場合) は、上記のサンプルで問題ありません。

複数のスレッドからアクセスする必要がある場合は、+sharedInstanceand+resetSharedInstanceメソッドをロックする必要があります。

+ (id)sharedInstance {
    @synchronized(self) {
        if (sharedInstance == nil) {
            sharedInstance = [[MySingleton alloc] init];
        }
        return sharedInstance;
    }
}

+ (void)resetSharedInstance {
    @synchronized(self) {
        sharedInstance = nil;
    }
}

これはバリアントよりもかなり遅くなりますdispatch_onceが、実際には通常は問題になりません。

于 2013-06-28T17:03:42.477 に答える
5

ええ、しかし、シングルトンのsharedInstanceメソッドはそれをstaticそのメソッドの内部として定義しており、最終的なコード サンプルはローカル変数 (偶然にも と呼ばれますshared) をnilに設定するだけで、static内部は変更されませんsharedInstance。したがって、内部をnil変更するのではなく、ローカル ポインターを -ing するだけです。staticsharedInstance

求めていることを実行したい場合は、メソッドからstatic変数をプルする必要があります(そして、おそらく何らかのメソッドをそれに書き込む必要があります)。あなたのメソッドも に依存することはできなくなりましたが、そうであるかどうかを確認する必要があります。sharedsharedInstanceresetnilsharedInstancedispatch_oncestaticnil

于 2013-06-28T17:00:21.560 に答える