2011-05-09 4 views
2

Я разрабатываю свое первое приложение «Дневник» для iphone, которое использует пользовательские объекты «Entry», которые содержат заголовок NSString, текст NSString и NSDate creationDate. Когда я пытаюсь архивировать объекты NSMutableArray of Entry, а затем извлекать их при следующем загрузке представления, приложение вылетает из строя. Я прошел через кучу примеров кода и примеров, которые используют NSKeyedArchivers, но все еще не мог понять, почему это происходит. Я предполагаю, что есть проблема с инициализацией массива, который содержит записи, но не уверены ...Не могу понять, почему мое приложение выходит из строя, когда я использую NSKeyedArchivers/NSKeyedUnarchivers

Вот код, может быть, вы могли бы найти что-то, что я упорно ... надзор»

//--------- 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

Куда он падает? – JeremyP

ответ

2

вы не должны освободить array в viewDidLoad, потому что вы не являетесь его владельцем.

Пожалуйста, ознакомьтесь с Cocoa memory management Rules, потому что есть несколько других ISS управления памятью в вашем коде. В частности,

self.title = [[aDecoder decodeObjectForKey:@"title"] retain]; 
self.text = [[aDecoder decodeObjectForKey:@"text"] retain]; 
self.created = [[aDecoder decodeObjectForKey:@"created"] retain]; 

в методе initWithCoder: все утечки в предположении, что свойства являются сохранить или скопировать.

+0

Спасибо, я посмотрю. И, в частности, приложение сбой при просмотре загрузилось. Я мог отследить его там, используя точки останова, но не понимал конкретно, какая строка вызывает его. – dg024

+0

Первоначально у меня было название и текст как NSStrings, и у меня было свойство «копировать», поэтому я изменил «сохранить» на «копировать». Благодарю. – dg024

3

Когда вы читаете массив с помощью NSKeyedUnarchivers, вы всегда получаете неизменяемую копию. Вам нужно объявить * массив как NSArray или просто избавиться от массива все вместе.

entriesArray = [[unarchiver decodeObjectForKey:@"entriesArray"] mutableCopy]; 

И @JeremyP указывает еще одну проблему. Поскольку вы не выделяли или не сохраняли * массив, вы не должны его отпускать.