2011-05-09 4 views
2

NSString 제목, NSString 텍스트 및 NSDate creationDate 보유하는 사용자 지정 'Entry'개체를 사용하여 첫 번째 아이폰 '일기'응용 프로그램을 개발하고 있습니다. Entry 객체의 NSMutableArray를 아카이브하고 나중에 뷰가로드 될 때 나중에 NSMutableArray를 검색하려고하면 응용 프로그램이 충돌합니다. 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

당신이 그것을 소유하지 않기 때문에 당신은 viewDidLoadarray를 공개해서는 안된다. 다른 메모리 관리 ISS의 몇 가지 있기 때문에

Cocoa memory management Rules을 검토하십시오 귀하의 코드에서 ues. 특히, 당신의 initWithCoder: 방법

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

모든 속성은 유지 또는 복사되는 가정에 누출.

+0

고마워, 나는 그것에 대해 조사 할 것이다. 그리고 특히보기에서 앱이로드되어로드되었습니다. 내가 거기에 중단 점을 사용하여 추적 할 수 있지만 구체적으로 어떤 라인을 일으키는 이해하지 못했습니다. – dg024

+0

처음에는 제목과 텍스트를 NSString으로 사용했으며 'copy'속성을 'copy'로 변경했습니다. 감사. – dg024

3

NSKeyedUnarchivers를 사용하여 배열을 읽어 들일 때 항상 변경 불가능한 복사본이 다시 나타납니다. * array를 NSArray로 선언하거나 배열을 모두 제거해야합니다.

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

그리고 @JeremyP는 다른 문제를 지적합니다. * 배열을 할당하거나 보관하지 않았으므로 해제하면 안됩니다.