2012-02-24 22 views
0

オブジェクトグラフをファイルに保存してから後で再読み込みしようとしていますが、decodeObjectForKey:は指定したキーに対して常にnilを返します。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]; 
} 

EDIT: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; 
} 

EDIT - アップデート(山車をエンコードするために必要とNSNumbersとしてint)

[NSKeyedArchiver archiveRootObject:object toFile:filePath]; 

をして使用してそれをロードします:

- (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"]; 
} 

答えて

6

を使用してデータをデコード あなたは、単一のルートオブジェクトを使用して直列化しますが、そのレベルでは存在しないキーを使用してデシリアライズしてみてください。

あなたはのように、unarchiveObjectWithData:をしたい:あなたもencodeWithCoder:への対応としてinitWithCoder:を実装する必要があります

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

注意。ここでシングルトンを使いたいと思うが、NSCodingは[NSKeyedArchiver archivedDataWithRootObject:sharedInstance]のためにここに新しいオブジェクトを作成することを要求している。

あなたはEN/PSYDefaultsの新しいインスタンスを作成せずにフィールドをデコードしたい場合は、(しかし、あなたはそれを別の名前を、次に与える必要があります)-[NSKeyedArchiver initForWritingWithMutableData:]を使用し、encodeWithCoder:と同様の方法にそのアーカイブを渡す必要があります。次に、NSKeyedUnarchiverを介してフィールドを読み取った相手を書くと、decodeObjectForKey:と各フィールドの友人が使用されます。

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

+0

これはすばらしいアドバイスです。ありがとうございます。私は保存して私の愚かさを認識し、今は新しいインスタンスを作成し、initWithCoderを実装しました。私はほぼそこにいると思うが、NSKeyedUnarchiverがオブジェクトグラフをアンアーカイヴすると、initWithCoderが呼び出される。しかし、私はinitWithCoder任意のアイデアを呼び出した後に悪いアクセスを得ていますか? Dave –

+0

Doh、それをこすってください。既に自動リリースされているときにnewInstanceを解放することが問題でした。あなたのすべての協力に感謝します!デイブ –

1

てみ使用してオブジェクトを保存し

[NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; 

私は、ファイルにカスタムオブジェクトとNSDictionaryのを保存するために、上記の方法を使用します。

また、あなたのオブジェクトにはinitWithCoder:(NSCoder *)デコーダが必要です。

[decoder decodeObjectFoyKey:yourKey]; 
+0

ありがとう、Hanon、DarkDustが最後にソートされました。あなたの答え+1を助けてくれました。 –

0

私はNSCoder'sdecodeObjectForKeyメソッドで別の問題がありましたが、何も説明せずにFXFormを使用しました。

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

メモリの問題が原因でした。一般的に、ログにバグの説明がない場合は、記憶上の問題です。私は正しいプロパティー属性コピーを使用するのを忘れていました。代わりにassignを使用しました。これは正しいコードです:

@interface MyClass : : NSObject <FXForm, NSCoding> 

@property (nonatomic, copy) SomeClass *someObject; 

@end 

もし誰かがこの問題にも合っていれば。

関連する問題