0

作成したカスタムオブジェクトクラスをnsuserdefaults配列に追加しようとしましたが、常に空のままです。私が取得しているログは次のとおりです。

「プロパティリストのディクショナリと配列にもプロパティ値のみが含まれている必要があることに注意してください」

私のコードは:

-(void)addProgramWithName:(NSString *)nameOfProgram andWithArrayOfIntervals:(NSMutableArray *)arrayOfIntervals{


    Program *tempProgram = [[Program alloc] init];
    tempProgram.nameOfProgram = nameOfProgram;
    tempProgram.arrayOfIntervals = arrayOfIntervals;

    NSMutableArray *tempArrayOfPrograms = [NSMutableArray arrayWithArray: [[NSUserDefaults standardUserDefaults] arrayForKey: @"arrayOfPrograms"]];

    [tempArrayOfPrograms addObject:tempProgram];

    [defaults setObject:tempArrayOfPrograms forKey:@"arrayOfPrograms"];

    [defaults synchronize];

}

その理由は何でしょうか?

4

2 に答える 2

1

問題の理由は、ログメッセージの内容です。プロパティリストの場合、配列(またはディクショナリ)に追加するオブジェクトはすべてプロパティ値(文字列、数値、日付、およびそれらの配列/ディクショナリ)である必要があります。

したがって、あなたの場合、ユーザーのデフォルトから値を読み込んだようです。次に、読み込んだ値にいくつかのカスタムオブジェクトを追加します。

修正された配列をユーザーのデフォルトに書き戻すつもりがない場合は、このアプローチに問題はありません(ただし、データ構造に対するややガンホーなアプローチだと思います)。

一方、データを書き戻す必要がある場合は、プロパティ値のみを配列に格納する必要があります。より複雑なオブジェクトの場合、キーと値を使用してディクショナリオブジェクトにエンコードすることで実現できます。

ただし、ニーズによっては、CoreDataの方がデータに適している場合があります。

于 2013-02-11T16:25:41.270 に答える
0

配列または辞書をNSUserDefaultsに格納すると、ディスク上のplistに凝縮されます。これは、カスタムオブジェクトをplistに保存できる形式に変換する必要があることを意味します。オブジェクトが保持するデータのタイプに応じてこれを行う方法はたくさんありますが、このメソッドはほとんどすべてのカスタムオブジェクトで機能し、かなり堅牢である必要があります。

Appleのうまく設計されたフレームワークのおかげで、それを実現するのは非常に簡単です:)

プロトコルをProgram.h追加します。<NSCoding>

@interface Program : NSObject <NSCoding>

次にProgram.m、次のメソッドを実装していることを確認してください。

#pragma mark - NSCoding

-(void)encodeWithCoder:(NSCoder *)encoder
{
    // For each of the Program's properties that needs to be stored.
    [encoder encodeObject:self.property forKey:@"PropertyKey"];
}

-(id)initWithCoder:(NSCoder *)decoder
{
    if (self=[super init]) {
        self.property = [decoder decodeObjectForKey:@"PropertyKey"];
    }

    return self;
}

このプロトコルとそのメソッドを使用すると、カスタムオブジェクトをその場でエンコードおよびデコードできます。これは、オブジェクトを適切な形式に変換できるようにするために重要です。

次に、配列を保存する前にアーカイブします。したがって、コードを次のように置き換えます。

// Old Line
// [defaults setObject:tempArrayOfPrograms forKey:@"arrayOfPrograms"];

// New Lines
id archivedObject = [NSKeyedArchiver archivedDataWithRootObject:tempArrayOfPrograms];
[defaults setObject:archivedObject forKey:@"arrayOfPrograms"];

最後のステップは、途中でアーカイブを解除していることを確認することです。したがって、アレイをロードする場所はどこでも、NSUserDefaults必ずアーカイブを解除してください。

// Get the archived array.
id archivedObject = [[NSUserDefaults standardUserDefaults] objectForKey:@"arrayOfPrograms"];

// Unarchive the array.
NSArray *unarchivedArray = [NSKeyedUnarchiver unarchiveObjectWithData:archivedObject];

// Its already a mutable array if you put a mutable array in but just to be safe.
NSMutableArray *arrayFromDefaults = [NSMutableArray arrayWithArray:unarchivedArray];
于 2013-02-11T16:27:27.130 に答える