0

NSコーディングを実装したオブジェクトがあります。私は一日中これで頭を悩ませてきました。私が理解していることから、私は NSCoding を実装しているため、配列自体でアーカイブ/アーカイブ解除メソッドが呼び出されたときに、配列のインデックスをエンコードおよびデコードする必要があります。したがって、それがどのように機能するかについての私の理解がずれているか、実装にいくつかのエラーがあります。

ファイルが書き込まれ、配列が逆シリアル化され、オブジェクトが含まれていることが示されます。しかし、配列内のクラスにはデータがありません。

実装は次のようになります。

#pragma mark NSCoding

#define kTitle              @"Title"
#define kDescription        @"Description"
#define kIsCompleted        @"IsCompleted"
#define kDate               @"Date"
#define kImage              @"Image"

-(id)initWithCoder:(NSCoder *)decoder
{
    [super init];
    title = [decoder decodeObjectForKey:kTitle];
    description = [decoder decodeObjectForKey:kDescription];
    isCompleted = [decoder decodeBoolForKey:kIsCompleted];
    date = [decoder decodeObjectForKey:kDate];
    image = [decoder decodeObjectForKey:kImage];

    return self;
}

-(void) encodeWithCoder:(NSCoder *) encoder
{
    [encoder encodeObject:title forKey:kTitle];
    [encoder encodeObject:description forKey:kDescription];
    [encoder encodeBool:isCompleted forKey:kIsCompleted];
    [encoder encodeObject:date forKey:kDate];
    [encoder encodeObject:image forKey:kImage];
}

@end

エンコーディングは次のようになります。トラブルシューティングの変更がいくつかあります。

-(void) writeFile
{
    NSData *encodedObject;
    encodedObject = [NSKeyedArchiver archivedDataWithRootObject: bucketItems];
    //NSFileHandle *file;
   // file = [NSFileHandle fileHandleForWritingAtPath:filePath];

    //if(true)//file == nil)
    //{
        //NSLog(@"Failed to open a file handle for writing. Attempting to create a file.");
        //[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
        //file = [NSFileHandle fileHandleForWritingAtPath:filePath];
        //if(file == nil)
        //{
         //   NSLog(@"Unable to create new file.");
       // }
    //}

    [encodedObject writeToFile:self.filePath atomically:YES];
    //[file writeData: encodedObject];
    //[file closeFile];
}

ここでデコードが行われ、プログラムが起動し、保存されたデータがあるかどうかを確認してロードします

NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:filePath];
        NSData *fileData;
        fileData = [file readDataToEndOfFile];
        bucketItems = [NSKeyedUnarchiver unarchiveObjectWithData:fileData];
        NSLog(@"Data file found: loading");
        [file closeFile];
4

1 に答える 1

1

あなたのメソッド内では、 toの結果を割り当てることと、インスタンス変数に直接割り当てられたオブジェクトを保持またはコピーするinitWithCoder:ことの 2 つが欠けていることがわかります。[super init] を自分自身に割り当てなくても済むかもしれませんが、インスタンス変数を保持しないと悲惨なことになります。[super init]self

手動参照カウント環境では、所有権を譲渡するメソッドが呼び出されない限り、オブジェクトはインスタンス変数に割り当てられた値の所有権を取得しません。これらのメソッドは、、、、およびnew/ ( Core Foundation の create および copy 関数も) です。それらのニーモニック デバイスとして頭字語 NARC を使用します。ivar に割り当てられたオブジェクトを作成したオブジェクト ( ) もオブジェクト自体もそれらを所有していないため、割り当てが解除されます。これを回避するには、ivar に割り当てたオブジェクトを保持またはコピーします。割り当てられているオブジェクトが変更可能であり、別のオブジェクトによって変更される可能性が高いと思われる場合は、不要な変更を防ぐためにコピーを行う必要があります。それ以外の場合は、値を保持します。最後に、呼び出して、これらのオブジェクトの所有権を確実に放棄してください。allocretaincopymutableCopyNSKeyedUnarchiverreleasedealloc、またはそれらにさらに割り当てを行う前に (合成または手動で実装されたセッター メソッドによって行う必要があります)。

最後にもう 1 つ-ファイルハンドラNSKeyedArchiverと. これは、エラー報告が不十分ですが、単純なケースではうまく機能します。NSKeyedUnarchiverarchiveRootObject:toFile:unarchiveObjectWithFile:NSFileManager

于 2013-04-02T01:38:40.457 に答える