0

オブジェクト グラフをファイルに保存し、後で再読み込みしようとしていますが、decodeObjectForKey: は指定したキーに対して常に nil を返します。

バイナリ ファイルが作成され、そこにはときどき人間が読めるテキスト、つまり titleTextColor が含まれているので、アーカイブ プロセスは機能していると思います。

NSKeyedArchiver と NSKeyedUnarchiver の仕組みを誤解していませんか? どんな助けでも大歓迎です。

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeFloat:titleFontSize forKey:@"titleFontSize"];
    [encoder encodeObject:[UIColor orangeColor] forKey:@"titleTextColor"];
    [encoder encodeObject:lineSeparatorColor forKey:@"lineSeparatorColor"];
    [encoder encodeObject:bodyTextColor forKey:@"bodyTextColor"];
    [encoder encodeFloat:bodyTextFontSize forKey:@"bodyTextFontSize"];
    [encoder encodeObject:backgroundColor forKey:@"backgroundColor"];
    [encoder encodeObject:tintColor forKey:@"tintColor"];
    [encoder encodeInteger:bodyTextAlignment forKey:@"bodyTextAlignment"];

    [encoder encodeObject:@"Text" forKey:@"Text"];
}

+ (void) saveToFile {
    // Get the shared instance
    PSYDefaults *sharedInstance = [PSYDefaults sharedInstance];    

    // Serialise the object
    NSData *serializedObject = [NSKeyedArchiver archivedDataWithRootObject:sharedInstance];

    // Get the path and filename of the file
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *pathAndFileName = [documentsDirectory stringByAppendingPathComponent:ksDefaultsFileName];

    // Write the defaults to a file
    if (serializedObject) [serializedObject writeToFile:pathAndFileName atomically:YES];
}

+ (void) loadFromFile {
    // Get the shared instance
    PSYDefaults *sharedInstance = [PSYDefaults sharedInstance];    

    // Get the path and filename of the file
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *pathAndFileName = [documentsDirectory stringByAppendingPathComponent:ksDefaultsFileName];

    NSData *codedData = [[[NSData alloc] initWithContentsOfFile:pathAndFileName] autorelease];
    NSKeyedUnarchiver *defaults = [[NSKeyedUnarchiver alloc] initForReadingWithData:codedData];

    // Set the properties of the shared instance
    NSString *test = [defaults decodeObjectForKey:@"Text"];
    NSLog (@"%@", test);
    sharedInstance.titleTextColor = [defaults decodeObjectForKey:@"titleTextColor"];

    [defaults release];
}

編集: DarkDust からのアドバイスに基づく:

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    if (self) {
        self.titleFontSize = [[aDecoder decodeObjectForKey:@"titleFontSize"] floatValue];
        self.titleTextColor = [aDecoder decodeObjectForKey:@"titleTextColor"];
        self.lineSeparatorColor = [aDecoder decodeObjectForKey:@"lineSeparatorColor"];
        self.bodyTextColor = [aDecoder decodeObjectForKey:@"bodyTextColor"];
        self.bodyTextFontSize = [[aDecoder decodeObjectForKey:@"bodyTextFontSize"] floatValue];
        self.backgroundColor = [aDecoder decodeObjectForKey:@"backgroundColor"];
        self.tintColor = [aDecoder decodeObjectForKey:@"tintColor"];
        self.bodyTextAlignment = [[aDecoder decodeObjectForKey:@"bodyTextAlignment"] intValue];
    }
    return self;
}

テストするためだけに新しいインスタンスを作成します。

+ (void) loadFromFile {
    // Get the shared instance
    PSYDefaults *sharedInstance = [PSYDefaults sharedInstance];    

    // Get the path and filename of the file
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *pathAndFileName = [documentsDirectory stringByAppendingPathComponent:ksDefaultsFileName];

    NSData *codedData = [[[NSData alloc] initWithContentsOfFile:pathAndFileName] autorelease];
    PSYDefaults *newInstance =  [NSKeyedUnarchiver unarchiveObjectWithData:codedData];

    sharedInstance.titleTextColor = newInstance.titleTextColor;
}

編集 - 更新 (float と int を NSNumbers としてエンコードする必要があります)

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:[NSNumber numberWithFloat:titleFontSize] forKey:@"titleFontSize"];
    [encoder encodeObject:titleTextColor forKey:@"titleTextColor"];
    [encoder encodeObject:lineSeparatorColor forKey:@"lineSeparatorColor"];
    [encoder encodeObject:bodyTextColor forKey:@"bodyTextColor"];
    [encoder encodeObject:[NSNumber numberWithFloat:bodyTextFontSize] forKey:@"bodyTextFontSize"];
    [encoder encodeObject:backgroundColor forKey:@"backgroundColor"];
    [encoder encodeObject:tintColor forKey:@"tintColor"];
    [encoder encodeObject:[NSNumber numberWithInt:bodyTextAlignment] forKey:@"bodyTextAlignment"];
}
4

3 に答える 3

6

単一のルート オブジェクトを使用してシリアライズしましたが、そのレベルに存在しないキーを使用してデシリアライズしようとしました。

unarchiveObjectWithData:次のように、次のようにします。

NSData *codedData = [[[NSData alloc] initWithContentsOfFile:pathAndFileName] autorelease];
PSYDefaults *decodedDefaults = [NSKeyedUnarchiver unarchiveObjectWithData:codedData];

initWithCoder:に対応するものとしても実装する必要があることに注意してくださいencodeWithCoder:。ここにシングルトンが必要なように見えますが、NSCoding は[NSKeyedArchiver archivedDataWithRootObject:sharedInstance].

の新しいインスタンスを作成せずにフィールドをエンコード/デコードする場合は、 -[NSKeyedArchiver initForWritingWithMutableData:]PSYDefaultsを使用して、そのアーカイブをあなたと同様のメソッドに渡す必要があります(ただし、別の名前を付ける必要があります)。次に、使用する場所と各フィールドの友人を介してフィールドを読み取る対応するものを作成します。encodeWithCoder:NSKeyedUnarchiverdecodeObjectForKey:

また、Apple のArchives and Serializations Programming Guideもお読みください。

于 2012-02-24T09:18:04.663 に答える
1

以下を使用してオブジェクトを保存してみてください。

[NSKeyedArchiver archiveRootObject:object toFile:filePath];

次を使用してロードします。

[NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

上記のメソッドを使用して、NSDictionary をカスタム オブジェクトと共にファイルに保存します。

また、オブジェクトに関数 initWithCoder:(NSCoder *)decoder が必要です。を使用してデータをデコードする

[decoder decodeObjectFoyKey:yourKey];
于 2012-02-24T09:17:10.230 に答える
0

NSCoder's decodeObjectForKey使用中にメソッドに別の問題がありましたFXForm-説明なしにクラッシュしました。

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

その理由はメモリの問題でした。一般的に、ログにバグの説明がない場合、それはメモリの問題であることを意味します。正しいプロパティ属性を使用するのを忘れていました - コピー。代わりに割り当てを使用しました。これは正しいコードです:

@interface MyClass : : NSObject <FXForm, NSCoding>

@property (nonatomic, copy) SomeClass *someObject;

@end

誰かがこの問題にも遭遇した場合に備えて。

于 2014-08-29T16:50:47.430 に答える