2

私は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
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

キャッシュ ディレクトリを削除すると、古いシリアル化されたデータが削除されました。

于 2014-06-15T20:41:15.123 に答える
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 に答える
0

最後に解決しました。次のパスが見つからなかったため、キャッシュからすべてを削除します。

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

そしてそれは働き始めました!奇妙な!

于 2013-07-13T21:14:28.607 に答える