2

我是 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,一个用于写入,另一个用于从文件中读取。它工作得很好。

当我使用 command+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

4 回答 4

2

initWithCoder:需要致电[super init];

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

    return self;
}
于 2013-07-13T04:57:06.163 回答
2

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

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

删除 Cache 目录摆脱了旧的序列化数据。

于 2014-06-15T20:41:15.123 回答
0

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

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

它开始工作了!奇怪!

于 2013-07-13T21:14:28.607 回答
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:49:38.357 回答