我正在开发我的第一个iphone'Diary'应用程序,它使用自定义'Entry'对象,其中包含NSString标题,NSString文本和NSDate creationDate。当我尝试存档Entry对象的NSMutableArray,并在下次加载视图时检索它们时,应用程序崩溃。我已经浏览了一堆使用NSKeyedArchivers的示例代码和示例,但仍然无法弄清楚为什么会发生这种情况。我猜测数据的初始化有一个问题,它保存条目但不确定......
这是代码,也许你可以找到我持续监督的东西......“
//--------- Entry.m---------------
- (id) initWithCoder:(NSCoder *)aDecoder{
if ((self = [super init])) {
self.title = [[aDecoder decodeObjectForKey:@"title"] retain];
self.text = [[aDecoder decodeObjectForKey:@"text"] retain];
self.created = [[aDecoder decodeObjectForKey:@"created"] retain];
}
return self;
}
- (void) encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.title forKey:@"title"];
[aCoder encodeObject:self.text forKey:@"text"];
[aCoder encodeObject:self.created forKey:@"created"];
}
//-------------- Diary View Controller.m
- (NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:kFilename];
}
- (void) writeDataToArchive {
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]
initForWritingWithMutableData:data];
[archiver encodeObject:self.entriesArray forKey:@"entriesArray"];
[archiver finishEncoding];
BOOL result = [data writeToFile:[self dataFilePath] atomically:YES];
[archiver release];
[data release];
}
- (void)addItem:sender {
int count = [entriesArray count] +1;
NSString *newEntryTitle = [NSString stringWithFormat:@"Entry %d", count];
Entry *anEntry = [[Entry alloc] initWithTitle:newEntryTitle text:@"-"
created:[NSDate date]];
[entriesArray addObject:anEntry];
[self.tableView reloadData];
[anEntry release];
[self writeDataToArchive];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSData *data = [[NSMutableData alloc]
initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]
initForReadingWithData:data];
NSMutableArray *array = [unarchiver decodeObjectForKey:@"entriesArray"];
entriesArray = [array mutableCopy];
[array release];
[unarchiver finishDecoding];
[unarchiver release];
[data release];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
// ... some other stuff
NSUInteger row = indexPath.row;
Entry *entry = [entriesArray objectAtIndex:row];
cell.textLabel.text = entry.title;
return cell;
}
非常感谢。
答案 0 :(得分:3)
当您使用NSKeyedUnarchivers读取数组时,您总是会得到一个不可复制的副本。你需要将*数组声明为NSArray,或者只是将数组一起删除。
entriesArray = [[unarchiver decodeObjectForKey:@"entriesArray"] mutableCopy];
@JeremyP指出了另一个问题。由于您没有分配或保留*数组,因此不应将其释放。
答案 1 :(得分:2)
您不应在array
中发布viewDidLoad
,因为您不拥有它。
请查看Cocoa memory management Rules,因为您的代码中存在其他一些内存管理问题。特别是,
self.title = [[aDecoder decodeObjectForKey:@"title"] retain];
self.text = [[aDecoder decodeObjectForKey:@"text"] retain];
self.created = [[aDecoder decodeObjectForKey:@"created"] retain];
在您的initWithCoder:
方法中,假设属性被保留或复制,所有泄漏都会泄漏。