私はobjective-cとcocoaが初めてで、ファイルシステムとの間でカスタムクラスを保存およびロードするドキュメントベースのアプリケーションを作成しようとしています。nscoding プロトコルに準拠する私のカスタム クラスは次のとおりです。
NSString *const 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 という 2 つのアクションを作成しました。1 つは書き込み用で、もう 1 つはファイルからの読み取り用です。それは完全にうまく機能します。
コマンド+ 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