2009-08-29 40 views
7

Cập nhật: Điều này có tác dụng nếu tôi gọi lưu trữRootObject: from applicationDidFinishLaunching :. Nếu tôi gọi nó từ init: phương thức của một lớp singleton, nó trả về nil.NSKeyedUnarchiver unarchiveObjectWithFile: trả về nil bằng init: phương thức

Tôi rất bối rối bởi hành vi của NSKeyedUnarchiver unarchiveObjectWithFile :. The documentation cho biết rằng nó sẽ trả về 0 nếu tệp không tồn tại. Với một trong các đối tượng của tôi, những điều sau xảy ra:

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 

Tôi đã xác minh rằng tệp thực sự tồn tại và được ghi vào phương pháp archiveRootObject :. Tôi đang làm gì sai khiến tôi không nhận được đối tượng Game trở lại trong kho lưu trữ?

+0

Tôi nghi ngờ điều này sẽ giải quyết câu hỏi của bạn, nhưng trong Mục tiêu-C, thuật ngữ thích hợp là 'BOOL' thay vì' bool'. – jbrennan

+0

Cảm ơn mẹo. Đây là dự án Objective-C đầu tiên của tôi. Tôi đã cập nhật tất cả các bool của tôi để BOOL của. – brantonb

+0

Đặt điểm ngắt tại objc_exception_throw và xem liệu có ngoại lệ không. – peterb

Trả lời

2
  1. Bạn phải luôn -retain một đối tượng không được lưu trữ: Game *g2 = [[NSKeyedUnarchiver unarchiveObjectWithFile:archivePath] retain];

  2. Liệu g2 của bạn phù hợp với NSCoding? Hãy chắc chắn rằng nó không, nếu nó không khai báo <NSCoding> trong tiêu đề g2. Trong tập tin thực hiện xác định phương pháp -(id)initWithCoder:(NSCoder *)coder-(void)encodeWithCoder:(NSCoder *)coder

  3. Nếu bạn đang đấu tranh để có được điều này để làm việc xem xét lưu trữ và hủy lưu trữ một NSObject tiêu chuẩn, như một NSString hoặc một số ví dụ. Có thể bạn không cần lưu trữ toàn bộ một đối tượng tùy chỉnh, có thể chỉ là số thời gian còn lại, vị trí trò chơi hoặc vị trí hoặc điểm số. Nói cách khác, lưu trữ và hủy lưu trữ số tiền tối thiểu bạn cần.

7

Tôi đã gặp những rắc rối tương tự trong Xcode 4.1 với sự hỗ trợ 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!!! 

Nó có vẻ là một lỗi trong cacao cảm ứng.

Edit:

Nó được thiết kế để cư xử như thế này và không phải là một lỗi. Nhưng tôi đồng ý rằng việc đặt tên dễ dàng dẫn đến những sai lầm.

[[NSKeyedUnarchiver alloc] initForReadingWithData:] trả về phiên bản NSKeyedUnarchiver.

[NSKeyedUnarchiver unarchiveObjectWithData:] trả về đối tượng gốc. Đó là phương pháp conviencen cho:

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

Cùng một vấn đề trên máy Mac. Cám ơn rất nhiều! –

Các vấn đề liên quan