1

iOS 開発の 2 番目のチュートリアルを完了しました。新しい目撃情報を追加すると、正常に機能し、目撃リストに表示されます。ただし、iOS シミュレーターを閉じて再度開くと、最初のエントリしかありません (手動で追加されます)。iOS シミュレーターを閉じて再度開いた後でも、iOS シミュレーターに内部メモリが必要ですか? 連絡先に連絡先情報を追加したかのように、いくつかの記憶があるようですが、それを再度開いてもまだそこにあります。その場合、DataController ファイルの配列がシミュレーター/電話に同様に保存されていることを確認して、シミュレーターを再度開くたびにそれ自体がクリアされないようにするにはどうすればよいですか?

ありがとう

4

1 に答える 1

2

セッション間でデータを保存する場合は、永続ストレージを使用する必要があります。オプションは次のとおりです。

  1. plist ファイルを使用できます。たとえば、 がある場合はNSArray *array、次を使用して plist に保存できますwriteToFile

    [array writeToFile:filename atomically:YES];
    

    次に、この配列を次のように読み取ることができます。

    NSArray *array = [NSArray arrayWithContentsOfFile:filename];
    

    ただし、この手法は標準NSStringNSNumber、 などのオブジェクトでのみ機能し、 のようなカスタム オブジェクトでは機能しませんBirdSighting

  2. のようなカスタム オブジェクトには、BirdSightingを使用できます。ところで、これらは、このような小さなデータ セットのデータを保存するための一般的に有用なクラスであるだけでなく、iOS 6 の新しい状態保存機能で際立って機能することを考えると、このパターンに慣れておく価値があります。NSKeyedArchiverNSKeyedUnarchiver

  3. 使用できますNSUserDefaults。これは、アプリの設定とデフォルトに非常に適していますが、理論的にはデータの保存にも使用できます。

  4. CoreDataを使用できます。これは、オブジェクトの永続化に推奨される iOS テクノロジです。これは強力でよく設計されたフレームワーク (少し複雑ですが) であり、より大量のデータを扱う場合に適しています。

  5. SQLiteも使用できます。SQLite の使用に関するこのRay Wenderlich の記事を参照してください。また、SQLite の使用を開始したら、FMDBを使用してコーディング作業を簡素化することを検討できます。


たとえば、2 番目のアプローチと を使用したい場合NSKeyedArchiverNSKeyedUnarchiver最初にすることは、 の宣言を次のように変更して、 にBirdSighting準拠させることです。NSCoding@interfaceBirdSighting.h

@interface BirdSighting : NSObject <NSCoding>

次に、 と の 2 つのメソッドを記述して、NSCodingこのオブジェクトに対してロード/保存できるプロパティを定義する必要があります。initWithCoderencodeWithCoderBirdSighting.m

- (NSArray *)keysForEncoding;
{
    return @[@"name", @"location", @"date"];
}

- (id) initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if (self) {
        for (NSString *key in [self keysForEncoding])
        {
            [self setValue:[aDecoder decodeObjectForKey:key] forKey:key];
        }
    }

    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    for (NSString *key in self.keysForEncoding)
    {
        [aCoder encodeObject:[self valueForKey:key] forKey:key];
    }
}

とでそれぞれBirdSightingロードおよび保存できるようになりました。NSKeyedUnarchiverNSKeyedArchiver

そのため、目撃情報の読み込みに焦点を当てると、(a)BirdSightingDataController.m検索するファイルを指定する必要があります。(b) 初期化中にそのファイルを読み取るように指示します。

- (NSString *)filename
{
    NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    return [docsPath stringByAppendingPathComponent:@"BirdSightings"];
}

- (void)initializeDefaultDataList
{
    NSString *filename = [self filename];

    self.masterBirdSightingList = nil;

    if ([[NSFileManager defaultManager] fileExistsAtPath:filename])
    {
        self.masterBirdSightingList = [NSKeyedUnarchiver unarchiveObjectWithFile:filename];
    }

    if (!self.masterBirdSightingList)
    {
        NSMutableArray *sightingList = [[NSMutableArray alloc] init];
        self.masterBirdSightingList = sightingList;
        BirdSighting *sighting;
        NSDate *today = [NSDate date];
        sighting = [[BirdSighting alloc] initWithName:@"Pigeon" location:@"Everywhere" date:today];
        [self addBirdSightingWithSighting:sighting];
    }
}

またBirdSightingDataController.m、データを保存するメソッドを定義することもできます。

- (BOOL)save
{
    return [NSKeyedArchiver archiveRootObject:self.masterBirdSightingList toFile:[self filename]];
}

saveたとえば、目撃情報を追加するたびにこのメソッドを呼び出すことができます。

- (void)addBirdSightingWithSighting:(BirdSighting *)sighting
{
    [self.masterBirdSightingList addObject:sighting];

    [self save];
}

個人的には、ユーザーがアプリに変更を加えるたびに保存するのではなく、アプリがバックグラウンドになるか終了するときにアプリのデリゲートに保存させることをお勧めします (ただし、それにはさらに変更が必要になるため、ここでは説明しません)。今)。

しかし、うまくいけば、このコードは、データを使用NSKeyArchiverNSKeyUnarchiverて保存およびロードする方法を示しています。そして明らかに、より複雑なシナリオでは、コア データを検討することをお勧めします。しかし、このような小さなデータ セットの場合は、このアーカイバ パターンが役立ちます (前述したように、基本的なテクノロジは iOS 6 アプリの状態の復元にも使用されるため、よく知っておく価値があります)。

于 2013-05-21T22:04:22.970 に答える