2

このリンクをたどる: NSKeyedArchiever を使用して 2 つのオブジェクトをアーカイブするにはどうすればよいですか? 配列とシングルトン オブジェクトをアーカイブできます。didFinishLaunchingWithOptions でアーカイブおよび正しく展開できます。

ただし、私のシングルトン オブジェクトはアプリ デリゲートを超えて保持されません。次のビュー コントローラーでは、didFinishLaunchingWithOptions で NSLog を実行して検証したにもかかわらず、シングルトン変数がデフォルト値に戻ります。ここに例があります、

アプリケーションでdidFinishLaunchingWithOptions:

Singleton *singleton = [Singleton sharedSingleton];
NSData *data = [NSData dataWithContentsOfFile:path];
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
singleton = [unarchiver decodeObjectForKey:@"singleton"];
[unarchiver finishDecoding];

NSLog(@"singleton sorting after decode: %@", [singleton sort]);// 出力: アルファベット

次に、viewController を割り当て/初期化し、ナビゲーション コントローラーのルート ビュー コントローラーとして設定します。

navController = [[UINavigationController alloc] initWithRootViewController:viewController];

viewController -> viewWillAppear で、

並べ替え関数を呼び出します: [self sort...];

ソート関数では、シングルトン クラスを呼び出します: Singleton*singleton = [Singleton sharedSingleton]; しかし、今、NSLog(@"singleton sort: %@", [singleton sort]);// 出力: 量 NOT アルファベット

Singleton コードを投稿できますが、動作することはわかっています。実際、ビュー コントローラーの設定で [singleton sort] 変数を変更すると、すべてのビュー コントローラーで永続化されます。

これは、私のシングルトン オブジェクトがアプリ デリゲートからビュー コントローラーに保持されない理由について、私を混乱させます。ヒント/ヒントをいただければ幸いです。

ありがとう!!!

編集: シングルトン クラスの実装

Singleton.m で:

static Singleton *shared = NULL;

+ (id)sharedSingleton
{
    @synchronized(self)
    {
        if ( !shared || shared == NULL )
        {
            // allocate the shared instance, because it hasn't been done yet
            NSLog(@"Allocating Singleton...");
            shared = [[Singleton alloc] init];
        }
        return shared;
    }
}


- (id)init
{
    if ( self = [super init] )
    {
        sort = [[NSString alloc] initWithString:@"amount"];
        showTutorial = YES;
    }
    return self;    
}

-(id)initWithCoder:(NSCoder *)aDecoder
{
    [super init];
    [self setSort:[aDecoder decodeObjectForKey:@"sort"]];
    [self setShowTutorial:[aDecoder decodeBoolForKey:@"showTutorial"]];

    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:sort forKey:@"sort"];
    [aCoder encodeBool:showTutorial forKey:@"showTutorial"];
}
4

5 に答える 5

2

シングルトンパターンが間違っていると思います。

コードで作成します

Singleton *singleton = [Singleton sharedSingleton];

これは正しいですが、やっています

singleton = [unarchiver decodeObjectForKey:@"singleton"];

シングルトンにはまったく意味がありません。一般的に言って、ペン先からシングルトンをインスタンス化することは望ましくありません。

于 2011-06-29T16:23:35.917 に答える
2

コードでは、sharedSingleton インスタンスではなく、現在のコンテキストでシングルトン ポインターの値を更新しているだけです

次のような unarchiver オブジェクトでシングルトン クラスを更新するメソッドをシングルトン クラスに作成してみてください。

[[Singleton sharedSingleton] loadArchive:unarchiver];

または(どちらが良いと思います)コードをSingleton init関数内に移動します。

于 2011-06-29T15:42:26.733 に答える
2

また、autorelease オブジェクトをローカル変数に割り当てました。このオブジェクトは、次回イベント ループを介して範囲外 (解放) になります。

singleton = [unarchiver decodeObjectForKey:@"singleton"];
于 2011-06-29T16:18:36.850 に答える
1

あなたのsingletonポインターは、最初に Singleton の共有インスタンスを指す単なるローカル変数です。singleton次に、アンアーカイバーからデコードしたオブジェクトを指すように値を変更します。このローカル ポインターが新しいシングルトンを指すようにしても、シングルトンの共有インスタンスは変更されず、グローバルの値も変更されません。shared

さらに、シングルトン パターンを誤解している可能性があると思います。シングルトン パターンは、クラスのインスタンスが 1 つしか存在できない場合に使用することになっています。グローバルに簡単にアクセスできるため、シングルトンがよく使用されますが、多くの賢明な人々は、この理由でシングルトンの使用をパターンの乱用と見なしています。この点については同意することも反対することもできますが、ここでの事実は、Singleton クラスの 2 つのインスタンスを作成していることであり、定義上、Singleton クラスはシングルトン デザイン パターンの真の実装ではないことを意味します。

于 2011-06-29T17:19:00.153 に答える
0

以下のコメントのほとんどは、元のコードで Singleton クラスの 2 つのインスタンスを作成していたという点で正しい方向を示しています。そして、私は自分の愚かさに気づいたので、ここに動作するコードがあります:

Singleton *singleton = [unarchiver decodeObjectForKey:@"singleton"];

次に、mySingleton の唯一のインスタンスを使用します。

Singleton *mySingleton = [Singleton sharedSingleton];
[mySingleton setSort:[singleton sort]];

したがって、このように、アンアーカイバーは、自動解放されたシングルトン オブジェクトのインスタンスをプルしますが、値は実際のシングルトン クラスに設定されます。

注: Singleton クラスを適切に使用していない可能性があるというコメントがいくつかありましたが、おそらくそうではありません。私はこれの専門家ではありません。何かを保存して、アプリが終了したときに元に戻したいだけです。それがあなたを助けるなら、素晴らしい。そうでない場合は、コメントを投稿して、私たち全員がよりよく学ぶのに役立ててください。私が良くなり、より多くのことを学べば、この投稿を更新するかもしれません。

しかし、すべてのコメントをありがとう。彼らは大丈夫です。私はそれらすべてに賛成票を投じました。

于 2011-06-29T18:36:34.890 に答える