- [NSKeyedUnarchiver decodeObjectForKey:]:无法解码类的对象(myCustomClass)

时间:2013-07-13 04:54:37

标签: objective-c cocoa nscoding

我是objective-c和cocoa的新手,并尝试创建一个基于文档的应用程序,该应用程序可以在文件系统中保存和加载自定义类。我的符合nscoding协议的自定义类如下:

NSString * const description = @“description”;

@implementation PhotoItem
@synthesize  description = _description;

-(id)init {
    if(self = [super init]){
        self.description = @"";
    }
    return self;
}

/* serializing into file */
- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.description forKey:description];
}

/* deserializing */
- (id)initWithCoder:(NSCoder *)aDecoder {
    self.description = [aDecoder decodeObjectForKey:description];
    return self;
}

和我的文件:

@implementation AMRDocument
@synthesize  imgMainImage = _imgMainImage, lblCreationDate = _lblCreationDate, photo=_photo,
txtDescription = _txtDescription;
- (id)init
{
    self = [super init];
    if (self) {
        self.photo = [[PhotoItem alloc] init];
    }
    return self;
}

- (NSString *)windowNibName
{
    return @"AMRDocument";

}

- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
    NSLog(@"windowControllerDidLoadNib");
    [super windowControllerDidLoadNib:aController];
//    self.imgMainImage.image = self.photo.image;
    [self.txtDescription setString: self.photo.description];
}


+ (BOOL)autosavesInPlace
{
    return YES;
}

#pragma mark -saving and loading
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
//    self.photo.image = self.imgMainImage.image;
//    return [NSKeyedArchiver archivedDataWithRootObject:self.photo];

    self.photo.description = self.txtDescription.string;
    NSData *archivedData  = [NSKeyedArchiver archivedDataWithRootObject:self.photo];
    return archivedData;
}

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{
    self.photo = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    return YES;
}



- (void)windowWillClose:(NSNotification *)notification {

}




- (IBAction)archiveClicked:(id)sender {
    self.photo = [NSKeyedUnarchiver unarchiveObjectWithFile:[@"~/desktop/myphoto1.photo"
            stringByExpandingTildeInPath]];

    [self.txtDescription setString:self.photo.description];
}

- (IBAction)archiveClicked:(id)sender {
    self.photo.description = self.txtDescription.string;
    [NSKeyedArchiver archiveRootObject:self.photo toFile:[@"~/desktop/myphoto1.photo"
            stringByExpandingTildeInPath]];
}
@end

正如你所看到的,我创建了两个名为archiveClicked和unarchiveClicked的动作,一个用于写入,另一个用于从文件中读取。 它完美无缺。

当我使用命令+ s保存文档时,它也可以成功写入文件,或者至少不会抛出任何异常。但是当我试图打开保存的文件时,它会在弹出窗口中给出以下异常,而不是运行应用程序并从磁盘加载。

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000


Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (PhotoItem)'
terminate called throwing an exception
abort() called

Application Specific Backtrace 1:
0   CoreFoundation                      0x00007fff8f715b06 __exceptionPreprocess + 198
1   libobjc.A.dylib                     0x00007fff912f03f0 objc_exception_throw + 43
2   CoreFoundation                      0x00007fff8f7158dc +[NSException raise:format:] + 204
3   Foundation                          0x00007fff98a1e8c3 _decodeObjectBinary + 2559
4   Foundation                          0x00007fff98a1dd24 _decodeObject + 226
5   Foundation                          0x00007fff98a90df3 +[NSKeyedUnarchiver unarchiveObjectWithData:] + 92
6   DocumentBasedApp                    0x0000000108e49a11 -[AMRDocument readFromData:ofType:error:] + 113
7   AppKit                              0x00007fff8d764527 -[NSDocument readFromURL:ofType:error:] + 546
8   AppKit                              0x00007fff8d365348 -[NSDocument _initWithContentsOfURL:ofType:error:] + 135
9   AppKit                              0x00007fff8d364ff4 -[NSDocument initWithContentsOfURL:ofType:error:] + 262
10  AppKit                              0x00007fff8d78d765 -[NSDocumentController makeDocumentWithContentsOfURL:ofType:error:] + 332
11  AppKit                              0x00007fff8d78ce7f __block_global_12 + 230
12  AppKit                              0x00007fff8d78ca1b __block_global_8 + 955
13  AppKit                              0x00007fff8d78bdba -[NSDocumentController _openDocumentWithContentsOfURL:usingProcedure:] + 593
14  AppKit                              0x00007fff8d78c655 __block_global_7 + 273
15  libdispatch.dylib                   0x00007fff926b4f01 _dispatch_call_block_and_release + 15
16  libdispatch.dylib                   0x00007fff926b10b6 _dispatch_client_callout + 8
17  libdispatch.dylib                   0x00007fff926b60c8 _dispatch_main_queue_callback_4CF + 275
18  CoreFoundation                      0x00007fff8f6b7b4c __CFRunLoopRun + 1644
19  CoreFoundation                      0x00007fff8f6b70e2 CFRunLoopRunSpecific + 290
20  HIToolbox                           0x00007fff8df91eb4 RunCurrentEventLoopInMode + 209
21  HIToolbox                           0x00007fff8df91b94 ReceiveNextEventCommon + 166
22  HIToolbox                           0x00007fff8df91ae3 BlockUntilNextEventMatchingListInMode + 62
23  AppKit                              0x00007fff8d44c533 _DPSNextEvent + 685
24  AppKit                              0x00007fff8d44bdf2 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 128
25  AppKit                              0x00007fff8d4431a3 -[NSApplication run] + 517
26  AppKit                              0x00007fff8d3e7bd6 NSApplicationMain + 869
27  DocumentBasedApp                    0x0000000108e49652 main + 34
28  libdyld.dylib                       0x00007fff8d2647e1 start + 0

我实际上创建了检查我的nscoding函数的正确性的操作,它似乎工作正常,但没有线索,也找不到与我的问题相关的任何内容。 感谢任何帮助。不用说这是我作业的一部分。

修改 此应用程序的名称是“PhotoManager”。之前我有另一个名为“DocumentBasedApp”的基于文档的应用程序,该例外以:

开头
Process:         DocumentBasedApp [4852]
Path:            /Users/USER/Library/Caches/*/DocumentBasedApp.app/Contents/MacOS/DocumentBasedApp
Identifier:      com.cjcoax.DocumentBasedApp
Version:         1.0 (1)
Code Type:       X86-64 (Native)
Parent Process:  launchd [132]
User ID:         501

4 个答案:

答案 0 :(得分:2)

您的initWithCoder:需要致电[super init];

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    if (self) {
        self.description = [aDecoder decodeObjectForKey:description];
    }

    return self;
}

答案 1 :(得分:2)

MyCustomClass的序列化版本与代码中的当前版本不同,可能是由于开发过程中的更改。

  

/用户/用户/资源库/缓存/ * / DocumentBasedApp.app/Contents/MacOS/DocumentBasedApp

删除缓存目录删除了旧的序列化数据。

答案 2 :(得分:0)

最后解决了,我从缓存中删除了所有内容,因为我找不到以下路径:

/Users/USER/Library/Caches/*/DocumentBasedApp.app/Contents/MacOS/DocumentBasedApp

它开始工作了!奇异!

答案 3 :(得分:0)

使用NSCoder's时,我遇到了decodeObjectForKey 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

以防有人遇到这个问题。