2011-06-29 8 views
2

このリンクの後に:How do I archive two objects using NSKeyedArchiever?配列とシングルトンオブジェクトを実現できます。 FinishedLaunchingWithOptionsで私はそれを達成し、正しく守ることができます。シングルトンは、アプリケーションデリゲートから別のビューコントローラに継承されません

しかし、私のシングルトンオブジェクトは、アプリケーションデリゲートを超えて持続しません。次のView Controllerでは、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]); //出力に含ま:

はその後、私はALLOCアルファベット/のViewControllerを初期化し、私のナビゲーションコントローラのルートビューコントローラとして設定します: ViewControllerで

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

- > viewWillAppear、

私はソート関数を呼び出します: [self sort ...];

やソート機能では、私は、シングルトンクラスを呼び出す: シングルトン*singleton = [Singleton sharedSingleton]; しかし、今、NSLog(@"singleton sort: %@", [singleton sort]); //出力:量

をアルファベットないで、私は私のシングルトンのコードを投稿することができますが、私はそれが動作を知っています。実際、私の設定ビューコントローラでは、[シングルトンソート]変数を変更すると、すべてのビューコントローラを通して保持されます。

これは、私のシングルトンオブジェクトがアプリケーションデリゲートからビューコントローラに永続しない理由を混乱させます。任意のヒント/ヒントが評価されます。

ありがとうございました!

EDIT:シングルトンクラスの実装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"]; 
} 
+0

'initWithCoder:'メソッドをどのように実装しましたか? –

+0

@Deepak。私は私のシングルトンクラスのコードを含めるように質問を更新しました。本当にありがとう!!! – okysabeni

答えて

2

あなただけsharedSingletonインスタンス

を現在のコンテキストでシングルトンポインタの値を更新していません

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

[[Singleton sharedSingleton] loadArchive:unarchiver]; 

または(これが良いと思いますが)あなたのコードをSingletonのinit関数の中に移動します。

+0

シングルトンのinit関数の中でコードを移動する方法を詳しく説明できますか?私は私のシングルトンクラスコードで質問を更新します。ありがとう。 – okysabeni

2

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

2

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

は、あなたは正しいですコード

Singleton *singleton = [Singleton sharedSingleton];

でそれを作成するのではなく、

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

がすべてでシングルトンのためにも意味がありませんやって。一般的に言えば、あなたはペン先からシングルトンをインスタンス化したくありません。

+0

申し訳ありませんが、私はあなたの答えを理解していません。私はペン先からSingletonをインスタンス化しなかった。私の考えでは、SingletonクラスはNSMutableArrayに似たオブジェクトであるNSObjectです。したがって、アプリケーションが中断すると、archieveは[archieve encodeOBject:singleton forKey:@ "singleton"]と呼ばれます。そのため、シングルトンオブジェクトをunarchieveするためにキー "singleton"を使用しています。私の論理に欠陥があると、もっと精巧に説明できますか?ありがとう。 @Yko。 – okysabeni

+0

。ああ、それはあなたの意図です。私はシングルトンの状態を保存することをお勧めしますアプリケーションがsupsendsとロードするときに再開します。私はそのロジックをシングルトンに入れました。つまり、キー付きアーチャーを使用するセーブ/リストアメソッドです。あなたはすでにインスタンスを生成した後に別のインスタンスをロードするように見えます。したがって、パターンを混乱させるでしょう。 – Eiko

+0

ありがとうございます。私はそれを調べます。確かに唯一のシングルトンオブジェクトを実現するのがより理にかなっています。アプリケーションが起動すると、シンプトンオブジェクトを起動するだけです。私はそれを見て、私のコードを少し改善します。 – okysabeni

1

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

さらに、シングルトンのパターンを誤解している可能性があります。シングルトンパターンは、クラスのインスタンスが複数存在することが許されない場合に使用されると想定されます。シングルトンはグローバルにアクセスするのが簡単なのでよく使用されますが、多くのスマート・ユーザーはシングルトンを使用してパターンの悪用を検討しています。この点については、同意するか同意できませんが、実際には、シングルトンクラスのインスタンスを2つ作成しているということです。定義すると、シングルトンクラスはシングルトンデザインパターンの真の実装ではありません。

+0

真。あなたと他の賢い人たちの意見に同感し、私はSingletonクラスのインスタンスを1つしか作成しません。しかし、どうしたらいいですか?私はSingletonを "Settings"変数に使用しています。この変数は、アプリのライフタイム全体を持続させ、アプリ全体を通して動作するので、Singletonモデルに合っていると思います。そして今、私はそれをアーカイブして、次回のアプリ起動時に "設定"を覚えています。それが私が本当に欲しいものです。興味深いことに、archieveRootObjectを使用して1つのシングルトンオブジェクトのみをアーカイブする別のアプリケーションでは、すべてが機能するようです。 – okysabeni

+0

@Yko、問題の根源は、共有シングルトンインスタンスを置き換えることです。真のシングルトンでは、元のインスタンスへの参照が格納されているオブジェクトがあるかどうかを知ることが難しいため、これを行うのは難しいです。あなたのシングルトンクラスを捨てて、iOSがあなたのアプリに設定情報を記録するために提供する本当のシングルトンを使うことを考えましたか? NSUserDefaultsはあなたが再考しようとしているものと思われます。 – Caleb

+0

Ahhはい。私はNSUserDefaultsを見回しましたが、私はおそらく私自身のSingletonクラスを使用して、もっと多くのものを追加する必要がある場合に備えて簡単にできると考えました。そして、何とかNSUserDefaultsを使用すると私を混乱させて困らせてしまい、.plistファイルを作成するときと何か関係があり、コードを変更した後にplistファイルの値が変更されたり、そんなことがないと思う。いずれにしても、デフォルトが変更されたときにはちょっと混乱してしまいます... – okysabeni

0

以下のコメントのほとんどは、オリジナルのコードで正しい方向を指していますが、私はシングルトンクラスの2つのインスタンスを作成していました。

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

を次に1とmySingletonの唯一のインスタンスを使用し、::だから

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

を、この方法は、una​​rchiverはのインスタンスを引っ張ると、私は動作するコードがあるので、ここで私の愚かさを実現します自動解放されたシングルトンオブジェクトですが、値は実際のシングルトンクラスに設定されています。

注:私はシングルトンクラスを正しく使用していない可能性があり、おそらくそうではないとの意見がありました。私はこれで専門家ではない。私はちょうど何かを保存し、アプリが終了するときに戻したいと思う。それがあなたを助けたら、素晴らしい。そうでない場合は、私たちすべてがよりよく学ぶのを助けるコメントを投稿してください。私がもっと良くなってもっと学ぶなら、多分私はこのポストを更新するでしょう。

すべてのコメントありがとうございます。彼らは大丈夫です。私はそれらのすべてをupvotedしました。

関連する問題