2013-04-02 96 views
0

所以我有一個對象,我已經實現NS編碼。我一整天都在用我的腦子一直在痛苦。根據我的理解,因爲我已經實現了NSCoding,所以在數組本身調用存檔/解除存檔方法時,應該對數組的索引進行編碼和解碼。所以無論我對它是如何工作的理解都是關閉的,或者我的實現有一些錯誤。iOS序列化/反序列化不能正常工作

該文件被寫入,並且陣列被反序列化,並將其顯示在它的對象。但是數組中的類沒有數據。

實施看起來是這樣的:

#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]; 
+0

是否調用了initWithCoder? – Rob

+0

啊這是..我沒有檢查,它看起來像場被解碼..現在爲什麼數組沒有看到正確初始化對象 –

+0

所以bucketItems並最終被同一陣列,具有每個項目正確的屬性?聽起來像你做的? (使用記錄斷點它轉儲到控制檯右側是未歸檔後..) – Rob

回答

1

在您的initWithCoder:方法,我看到缺少兩件事 - 將[super init]的結果分配給self,並保留或複製直接分配給實例變量的任何對象。你也許能夠不用爲自己分配[super init],但不保留實例變量將是災難性的。

在手動引用計數環境,對象不採取分配給實例變量值的所有權,除非該所有權轉移的方法被調用。這些方法是newallocretaincopy/mutableCopy(也Core Foundation中創建和複製功能)。使用縮寫NARC作爲這些助記符的設備。由於既沒有創建分配給ivars的對象(NSKeyedUnarchiver)擁有它們的對象,也沒有對象本身,它們被釋放。爲避免這種情況,請保留或複製您分配給ivars的對象。如果您懷疑被分配的對象可能是可變的並且可能被另一個對象突變,則應該進行復制以防止不必要的變異。否則,保留這些值。最後,通過在dealloc中調用release,或在對它們進行任何進一步分配(應由合成或手動執行的setter方法完成)之前,確保您放棄這些對象的所有權。

最後一兩件事 - 你可以使用NSKeyedArchiverNSKeyedUnarchiver方法archiveRootObject:toFile:unarchiveObjectWithFile:,而不是處理文件處理程序和NSFileManager。這對於簡單的案例來說很好,儘管它的錯誤報告很差。

相關問題