2009-08-29 37 views
7

更新:如果我從applicationDidFinishLaunching:中調用archiveRootObject:這會起作用。如果我從單例類的init:方法調用它,它將返回nil。NSKeyedUnarchiver unarchiveObjectWithFile:在init中返回nil:方法

我非常困惑的行爲NSKeyedUnarchiver unarchiveObjectWithFile :. The documentation表示如果文件不存在,它將返回nil。隨着我的對象之一,會發生以下情況:

Game *g1 = [Game getGame]; 
NSString *archivePath = [Game getArchivePath]; 
bool success = [NSKeyedArchiver archiveRootObject:g1 toFile:archivePath]; 
Game *g2 = [NSKeyedUnarchiver unarchiveObjectWithFile:archivePath]; 

// success is true, g2 is nil 

我已經驗證該文件實際上確實存在,並通過archiveRootObject是越來越寫到:方法。我做錯了什麼阻止我將Game對象從存檔中取出?

+0

我懷疑這會解決你的問題,但在Objective-C中,正確的術語是'BOOL'而不是'bool'。 – jbrennan 2009-08-29 21:31:35

+0

感謝您的提示。這是我的第一個Objective-C項目。我已經更新了所有布爾的BOOL。 – brantonb 2009-08-30 05:18:12

+0

在objc_exception_throw上設置一個斷點並查看是否引發異常。 – peterb 2009-08-30 13:18:31

回答

2
  1. 你必須始終-retain未歸檔對象:Game *g2 = [[NSKeyedUnarchiver unarchiveObjectWithFile:archivePath] retain];

  2. g2符合NSCoding?確保它確實如果它不在g2標頭中聲明<NSCoding>。在實現文件中定義方法-(id)initWithCoder:(NSCoder *)coder-(void)encodeWithCoder:(NSCoder *)coder

  3. 如果你努力得到這個工作考慮封存和解除封存標準NSObject的,像一個NSString或一些這樣的。您可能不需要歸檔整個自定義對象,可能只是剩餘的時間編號,遊戲位置或位置或得分。換句話說,存檔和取消存檔您需要的最低限度。

7

我已經滿足在Xcode 4.1一樣的煩惱與ARC支持:

BOOL isFileExist = [[NSFileManager defaultManager] fileExistsAtPath:filePath]; 
NSAssert(isFileExist, @"filePath does not exist"); 
NSKeyedUnarchiver* coder = 
    [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; // nil 
NSData* data = [[NSFileManager defaultManager] contentsAtPath:filePath]; 
coder = [NSKeyedUnarchiver unarchiveObjectWithData:data]; // nil 
coder = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; // OK!!! 

這似乎是在可可觸摸的錯誤。

編輯:

它的目的是這樣的表現,是不是一個錯誤。但我同意命名容易導致錯誤。

[[NSKeyedUnarchiver alloc] initForReadingWithData:]返回NSKeyedUnarchiver實例。

[NSKeyedUnarchiver unarchiveObjectWithData:]返回根對象。這是一種conviencen方法:

NSKeyedUnarchiver *coder = [[self alloc] initForReadingWithData:arg2]; 
id object = [coder decodeObjectForKey:@"root"]; 
+1

Mac上也出現同樣的問題。非常感謝! – 2012-01-11 02:10:17

相關問題