2013-07-13 3 views
2

objective-c 및 cocoa를 처음 사용하고 파일 시스템에서 사용자 정의 클래스를 저장하고로드하는 문서 기반 애플리케이션을 만들려고합니다. nscoding 프로토콜을 따르는 사용자 정의 클래스는 다음과 같습니다.- [NSKeyedUnarchiver decodeObjectForKey :] : 클래스 (myCustomClass)의 객체를 디코딩 할 수 없습니다.

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를 사용하여 문서를 저장할 때 파일에 성공적으로 쓸 수도 있고 적어도 예외가 throw 될 수 있습니다. 그러나 저장된 파일을 열려고 할 때 응용 프로그램을 실행하지 않고 디스크에서로드하는 대신 팝업에서 예외가 발생합니다.

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"라는 다른 문서 기반의 응용 프로그램을 가지고 있었고, 예외로 시작 [super init]; 전화를

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 
+5

'description'속성의 이름을 지정하지 마십시오. 'NSObject' 클래스에는'description'이라는 표준 메소드가 있습니다. 이 문제의 원인은 의심 스럽지만 다른 문제가 발생할 수 있습니다. – rmaddy

+0

'archiveRootObject'의 부울 반환 값을 확인하고 성공했는지 확인하는 것이 좋습니다. – Rob

답변

0

마지막으로 나는 다음과 같은 경로를 찾을 수 없습니다, 나는이 캐시에서 모두 삭제 해결 :

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

그것은 일을 시작! 기괴한!

2

귀하의 initWithCoder: 필요.

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

    return self; 
} 
+0

고맙지 만 문제는 계속 유지됩니다. – CjCoax

2

MyCustomClass의 직렬화 된 버전은 개발 중 변경으로 인해 코드의 현재 버전과 다릅니다. 캐시 디렉토리를 삭제 /Users/USER/Library/Caches/*/DocumentBasedApp.app/Contents/MacOS/DocumentBasedApp

은 기존의 직렬화 된 데이터를 제거되었다.

0

FXForm을 사용하는 동안 나는 NSCoder'sdecodeObjectForKey 방법에 또 다른 문제가 있습니다. 아무런 설명없이 충돌했습니다.

- (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 

누군가가이 문제를 해결할 수도 있습니다.

관련 문제