1

私はこのトピックについて長く懸命に調査しましたが、解決策を見つけることができません。私はxcodeでのiPhoneアプリ開発に非常に慣れていないので、答えを分かりやすくしてください笑。Appleの「Your Second iOS App」チュートリアルに従い、マスター詳細アプリを完全に機能させましたが、ユーザーが入力したデータを保存して、アプリをリセットした後に表示されるようにしたいと考えています。コードは、こちらのアップルチュートリアルにあるものと同じです

前もって感謝します!

4

1 に答える 1

2

データを保存する方法と、いつデータを保存/取得するかという 2 つの主な決定を行う必要があります。まずはデータの保存方法から。

データの保存方法

実行できる主な方法は 3 つあります。ファイルに保存する、SQLite データベースに保存する (FMDB などのラッパーの有無にかかわらず)、CoreData を使用することです。最終的には SQLite と CoreData をマスターしたいと思うでしょうが、今のところは最初のアプローチを取ることをお勧めします。

ファイルに保存/ファイルから読み取る場合は、フォーマットを決定する必要があります。XML、JSON、独自のカスタム形式など、さまざまなオプションがあります。実際、「実際の」プロジェクトでは、プロジェクトの目標によっては、JSON などの形式が適切な選択になる可能性があります。ただし、多くの仕組みがすでに整っているため、シリアル化されたアーカイブの使用について説明します。

データをアーカイブに保存するには、NSKeyedArchverを使用してデータをファイルに書き込みます。後で、NSKeyedUnarchiverを使用してファイルから情報を取得します。これらのクラスは、データをバイトストリームとの間でエンコード/デコードし、ネットワーク経由で送信したり、ファイルに書き込んだりできます。

主なデータ構造は masterBirdSightingList という名前のNSMutableArrayであるため、アーカイバーは配列をエンコードする必要があります。NSArray とそれに対応する変更可能なものは、自分自身をエンコード/デコードする方法をすでに知っています。それらは、いくつかの簿記情報とともに各要素をエンコード/デコードするだけです。そのため、パズルには欠けているピースがあります。BirdSighting クラスのインスタンスをエンコード/デコードする方法を指定する必要があります。

これを指定するには、 NSCodingプロトコルを実装するようにクラスを変更します。BirdSighting.hで、 @interface 宣言を次のように変更します。

@interface BirdSighting : NSObject <NSCoding>

NSCoding の実装は簡単です。上で述べたように、さまざまな配列クラスは自分自身をエンコード/デコードする方法を知っています。つまり、それらは既に NSCoding プロトコルを実装しています。BirdSighting をエンコード/デコードするには、クラスの各データ メンバーをエンコード/デコードするだけです。ソース コードを見ると、2 つの NSString と 1 つの NSDate であることがわかります。しかし、これらの各クラスはすでに NSCoding も実装しています。したがって、BirdSighting インスタンスをエンコード/デコードするには、各インスタンス変数に自分自身をエンコード/デコードするように指示する必要があります。この作業はすべて、BirdSighting クラスに追加するメソッドinitWithCoder:およびencodeWithCoder:で行います。

: 私が詳しく説明している詳細の 1 つは、アーカイバーと鍵付きアーカイバーの違いです。通常、キー付きアーカイバーを使用することになるため、3 つのマクロ定義を使用します。正直なところ、マクロではなく静的な NSString 定数として NAME_KEY などを作成します。

#define NAME_KEY @"name"
#define LOCATION_KEY @"location"
#define DATE_KEY @"date"

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init]; 
    if (self) {
       _name = [aDecoder decodeObjectForKey:NAME_KEY];
       _location = [aDecoder decodeObjectForKey:LOCATION_KEY];
       _date = [aDecoder decodeObjectForKey:DATE_KEY];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{
   [aCoder encodeObject:self.name forKey:NAME_KEY];
   [aCoder encodeObject:self.location forKey:LOCATION_KEY];
   [aCoder encodeObject:self.date forKey:DATE_KEY];
}

もう 1 つ注意してください。BirdSighting は NSObject (NSCoding を実装していません) から直接継承するため、私はself = [super init]. 親クラスNSCoding を実装している場合は、実行する必要がありますself = [super initWithCoder:aCoder]

上記が整っていれば、ファイルへの保存/ファイルからの読み込みは簡単です。BirdSightingDataController のどこかに、おそらくinitializeDefaultDataListに、以下を挿入します。

masterBirdSightingList = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

ここで、pathは、アーカイブ ファイルへのディレクトリ パスと、本番コードでのエラー チェックと処理の必要性に関する通常の注意事項 (ファイルが存在しない場合など) を含む NSString です。

データの保存も簡単です。次のようなメソッドを BirdSightingDataController オブジェクトに追加できます。

- (BOOL)archiveToPath:(NSString *)path
{
    BOOL success = [NSKeyedArchiver archiveRootObject:self.masterBirdSightingList];
    return success;
}

データを保存するタイミング

データを保存および復元するためのコードが用意できたので、これらの操作をいつ実行するかを決定する必要があります。ここでは、アプリ全体の構造など、他の問題が関係するため、もう少しあいまいになります。ただし、アプリケーション デリゲートは、 applicationWillResignActive:applicationWillEnterForeground:などのバックグラウンドでの実行に関連するメソッドがあるため、リストのアーカイブとアーカイブ解除を管理する候補となる可能性があります。

バックグラウンドに移行する前に、目撃情報リストのメモリ内コピーを削除することをお勧めします。これは、アプリ デリゲートにアーカイブを作成するコードを配置することを提案しています。逆に、リストの遅延読み込みを検討する必要があります。つまり、表示する準備ができるまでリストを取得しないでください。これは、リストを取得するコードを BirdSightingDataController の init メソッドに入れることを提案しています。

ここでの課題は、アプリを過度に結合したり複雑化したりすることなく、これらすべてを行うことです。しかし、その議論は別の Q&A に任せます。

于 2013-05-15T16:41:32.820 に答える