[[ともっくす alloc] init]

ともっくすの雑多な日記と技術的なメモ

NSKeyedUnarchiverを使ってアーカイブを復元しようと思ってもnilしか返ってこない

iPhoneアプリを作っていて,データのシリアライズをしようと思い,NSKeyedArchiverのarchiveRootObject:toFile:メソッドでアーカイブして,NSKeyedUnarchiverのunarchiveObjectWithFile:メソッドでアンアーカイブしようと思った.

しかし,保存はできるが,復元ができない.nilが返ってきてしまう.

独自クラスを使ってはいるが,ちゃんと,initWithCoder:とencodeWithCoder:は実装してある.

unarchiveObjectWithFile:メソッドでnilが返ってくるのは,ファイルが存在しなかったときらしいが,ファイルはしっかりと存在している.

詰まった.

initWithCoder:内にNSLogを記述して,プリントデバッグをしてみるも,なんと,そもそもinitWithCoder:すら呼ばれていない.

なぜだ.

詰まった.


みんなの頼れるGoogle先生に聞いてみるも,同じ症状の人は見つけられない.

StackOverflowで検索してみるも,見つからない.*1

で,がんばって探していると,こんなページを発見.
> シングルトンパターンでNSCodingを使用する場合の注意点 » MOKYN

「そういえば,俺,シングルトンパターン使ってるじゃん」と.

偶然発見したこのページに解決方法らしきものが載っていた.

+ (id)allocWithZone:(NSZone *)zone
{
    @synchronized(self) {
        if (sharedHogeDataManager == nil) {
            sharedHogeDataManager = [super allocWithZone:zone];
            return sharedHogeDataManager;
        }
    }
//    return nil; // ←コレが原因
    return sharedHogeDataManager;  // インスタンスを返す
}

allocWithZone:メソッドを変更すればいいらしい.

なるほど,ひたすらにnilが返ってきたのもわかるかもしれない.

ただ,このページの作者さんによると,

この解決方法が本当に正しいやり方なのか、シングルトンパターンが崩れているんじゃないか?とか非常に不安なところではあるのですが、とりあえずこれで動いたので同じ現象でお困りの皆様の参考になればと思い共有します。

こんなやり方じゃ駄目だ!という博識の方がいましたら是非ご教授をm(_ _)m

ということなので,もし,詳しい方がいれば,ご教授ください.


でも,とりあえず,解決したので良かった.

それに,厳密なシングルトンパターンに拘るほどのものではないので,これでいいでしょう.

*1:英語力が足りなくて見落としている可能性は多分にある.