3

賞金を設定した後、答えを見つけました。誰かが私のアプローチについて有益なコメントを持っている場合 (それが「正しい」解決策かどうかはわかりません)、その人は報奨金を受け取ることができます。私の質問に反対票を投じる場合は、今後の質問を改善できるようにコメントを残してください。

私は現在、本でObjective-Cを学んでおりCocoa Programming For Mac OS X、第10章でアーカイブを紹介しています。私(AFAIK)は、著者が私に望んでいることを正確に行いましたが、ファイルを開いてアーカイブを解除すると、アプリが次の行でクラッシュします:

array = [NSKeyedUnarchiver unarchiveObjectWithData:data];

それは言いGDB received signal: EXC_BAD_ACCESSます。範囲外の配列スロットにアクセスするときにのみこれに遭遇しましたが、そうしていないと思います。私の推測では、Cocoa の舞台裏で何かがうまくいかず、間接的に私が原因であると考えられます。これは何ですか?
私が言ったように、私は現在 Objective-C を学んでいます (しかし、私は Java を知っています)。

ファイルを開く方法 ( MyDocument.m):

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError {
    NSMutableArray *array = nil;
    NSLog(@"data is %@", data);

    @try {
        array = [NSKeyedUnarchiver unarchiveObjectWithData:data]; // line of the EXC_BAD_ACCESS
    }
    @catch (NSException * e) {
        if (outError) {
            NSDictionary *d = [NSDictionary dictionaryWithObject:@"The data is corrupted." forKey:NSLocalizedFailureReasonErrorKey];
            *outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:d];
        }
        return NO;
    }
    [self setEmployees:array];
    return YES;
}

ファイルの保存方法(まだMyDocument.m):

- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
    [[tv window] endEditingFor:nil]; // tv is my IBOutlet to an NSTableView

    return [NSKeyedArchiver archivedDataWithRootObject:employees];
}

これはスタック トレースです (ありがとう、H2CO3):

(gdb) bt
#0  0x00007fff858da104 in objc_msgSend_vtable13 ()
#1  0x00007fff858dcff5 in objc_getProperty ()
#2  0x00000001000022cf in -[Person name] (self=0x1001d4480, _cmd=0x7fff89d1a790) at /Users/mauritsfriedrichkoelmans/Desktop/RaiseMan1/Person.m:14
#3  0x00007fff86e79674 in -[NSObject(NSKeyValueCoding) valueForKey:] ()
#4  0x00007fff86e7cfb8 in -[NSObject(NSKeyValueCoding) valueForKeyPath:] ()
#5  0x00007fff897e10df in -[NSBinder valueForBinding:atIndex:resolveMarkersToPlaceholders:] ()
#6  0x00007fff89682aa2 in -[NSValueBinder _adjustObject:mode:observedController:observedKeyPath:context:editableState:adjustState:] ()
#7  0x00007fff897e0e75 in -[NSValueBinder updateTableColumnDataCell:forDisplayAtIndex:] ()
#8  0x00007fff897e0d83 in -[NSTextValueBinder updateTableColumnDataCell:forDisplayAtIndex:] ()
#9  0x00007fff897e0d30 in -[_NSBindingAdaptor tableColumn:willDisplayCell:row:] ()
#10 0x00007fff896cab00 in -[NSTableView preparedCellAtColumn:row:] ()
#11 0x00007fff896ca306 in -[NSTableView _dirtyVisibleCellsForKeyStateChange] ()
#12 0x00007fff896c9e96 in -[NSTableView _windowChangedKeyState] ()
#13 0x00007fff88ba0d3e in CFArrayApplyFunction ()
#14 0x00007fff89611478 in -[NSView _windowChangedKeyState] ()
#15 0x00007fff88ba0d3e in CFArrayApplyFunction ()
#16 0x00007fff89611478 in -[NSView _windowChangedKeyState] ()
#17 0x00007fff88ba0d3e in CFArrayApplyFunction ()
#18 0x00007fff89611478 in -[NSView _windowChangedKeyState] ()
#19 0x00007fff88ba0d3e in CFArrayApplyFunction ()
#20 0x00007fff89611478 in -[NSView _windowChangedKeyState] ()
#21 0x00007fff896c991f in -[NSFrameView _windowChangedKeyState] ()
#22 0x00007fff89611171 in -[NSWindow _setFrameNeedsDisplay:] ()
#23 0x00007fff8960f1d8 in -[NSWindow _makeKeyRegardlessOfVisibility] ()
#24 0x00007fff8960f13e in -[NSWindow makeKeyAndOrderFront:] ()
#25 0x00007fff89814401 in -[NSWindowController showWindow:] ()
#26 0x00007fff897e5c5c in -[NSDocument showWindows] ()
#27 0x00007fff899539c1 in -[NSDocumentController openDocumentWithContentsOfURL:display:error:] ()
#28 0x00007fff89953072 in -[NSDocumentController _openDocumentsWithContentsOfURLs:display:presentErrors:] ()
#29 0x00007fff8976eeda in -[NSApplication sendAction:to:from:] ()
#30 0x00007fff8979346a in -[NSMenuItem _corePerformAction] ()
#31 0x00007fff897931d4 in -[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] ()
#32 0x00007fff89778e45 in -[NSMenu performKeyEquivalent:] ()
#33 0x00007fff89777bed in -[NSApplication _handleKeyEquivalent:] ()
#34 0x00007fff896486b9 in -[NSApplication sendEvent:] ()
#35 0x00007fff895df6de in -[NSApplication run] ()
#36 0x00007fff895d83b0 in NSApplicationMain ()
#37 0x0000000100001e9b in main (argc=1, argv=0x7fff5fbff660) at /Users/mauritsfriedrichkoelmans/Desktop/RaiseMan1/main.m:13
(gdb) 

データ オブジェクトはnil ではありませんNSLog()。編集してください。

4

3 に答える 3

7

私はそれを自分で解決しました!

本でinitWithCoder:は、 Person クラスのメソッド (アーカイブを解除しようとしている配列は、そのクラスのインスタンスで満たされています) は次のようになります。

- (id)initWithCoder:(NSCoder *)coder {
    [super init];
    name = [coder decodeObjectForKey:@"name"];
    expectedRaise = [coder decodeFloatForKey:@"expectedRaise"];
    return self;
}

しかし、それは次のようでなければなりませんでした:

- (id)initWithCoder:(NSCoder *)coder {
    [super init];
    self.name = [coder decodeObjectForKey:@"name"];
    self.expectedRaise = [coder decodeFloatForKey:@"expectedRaise"];
    return self;
}
于 2012-12-12T09:42:45.313 に答える
3

私の経験では、あなたのdataオブジェクトはnil

于 2012-11-28T16:58:06.947 に答える
3

保存が成功したことを確認します。

if (![NSKeyedArchiver archiveRootObject:myDictionary toFile:path])
{
    // saving failed for some reason
    return;
}

また、アーカイブを解除する前に、ファイルが存在することを確認してください。

if ([[NSFileManager defaultManager] fileExistsAtPath:path])
{
    // file does not exist at path (deleted?)
    return;
}
于 2012-12-19T02:17:06.237 に答える