2010-01-08 31 views
5

Tôi đang gặp sự cố với dữ liệu lõi/NSFetchedResultsController. Tôi không hoàn toàn chắc chắn nơi lỗi là thông điệp là khá mơ hồ.Dữ liệu lõi/lỗi NSFetchedResultsBộ điều khiển

Tôi gặp sự cố khi chèn nhiều đối tượng khi trình điều khiển kết quả tìm nạp không tìm nạp đối tượng. Các mã sau đây sẽ sụp đổ với các lỗi sau đây nếu tôi cố gắng và chèn một số đối tượng không có lấy. Nó không sụp đổ nếu tôi sử dụng nó để chèn một đối tượng, và nó không sụp đổ nếu đã có các đối tượng được tìm nạp.

Sự cố xảy ra trên phương thức save :. tiêu đề trong một NSArray và trong ví dụ này nó chứa 5 chuỗi.

Lỗi ứng dụng nghiêm trọng. Ngoại lệ đã bị bắt trong Core Data thay đổi chế biến: * - [NSCFArray objectAtIndex:]: chỉ mục (4) vượt giới hạn (1) với UserInfo (null) * Chấm dứt ứng dụng do ngoại lệ còn tự do 'NSRangeException', lý do : '*** - [NSCFArray objectAtIndex:]: chỉ mục (4) vượt quá giới hạn (1)'

NSEnumerator *titleEnumerator = [titles objectEnumerator]; 
NSString *title; 
NSMutableArray *tasks = [NSMutableArray array]; 
Todo *todo; 

while(title = [titleEnumerator nextObject]) 
{ 
    todo = (Todo *)[NSEntityDescription insertNewObjectForEntityForName:@"Todo" inManagedObjectContext:managedObjectContext]; 
    todo.title = title; 
    todo.state = [NSNumber numberWithInteger:TodoStateIncomplete]; 
    todo.priority = [NSNumber numberWithInteger:TodoPriorityNormal]; 
    todo.timeStamp = [NSDate date]; 
    todo.dueDate = [NSDate distantFuture]; 
} 

NSError *error; 

if(![managedObjectContext save:&error]) 
{ 
    NSLog(@"Unresolved error %@ %@", error, [error userInfo]); 
    abort(); 
} 
+0

tôi đã quản lý để có được xung quanh vụ tai nạn với một chút của một hack tinh ranh. Trong vòng lặp, tôi kiểm tra xem đó là lần đầu tiên. Nếu đó là tôi lưu. Điều này hoạt động như thể tôi chỉ thêm một đối tượng lúc đầu, điều này ngăn cản nó bị lỗi khi tôi thêm nhiều. Điều này sẽ giúp tôi nhưng tôi vẫn muốn biết tại sao điều này lại xảy ra để tôi có thể sửa nó đúng cách. –

Trả lời

5

đây là một mẹo từ Marcus Zarra (tác giả của cuốn sách Core Data):

Core Data error when deleting row in tableView

"Thử phá vỡ objc_exception_throw và xem phương pháp nào đang ném ngoại lệ. Điều đó sẽ giúp theo dõi nó xuống "

+0

Theo lời khuyên từ Marcus (một lần nữa!), Điều này nhắc tôi về mục nhập blog Jeff Lamarche cho một phiên bản cập nhật mẫu dữ liệu cốt lõi dựa trên nav của Apple: http://iphonedevelopment.blogspot.com/2010/01/navigation dựa trên-core-dữ liệu-ứng dụng.html – petert

0

Tôi biết đó không phải là câu trả lời, nhưng vì sự cố xảy ra khi lưu: và tôi nhớ có lỗi lạ với lần này ... Lỗi mà tôi đã khắc phục lỗi này cách nào, tôi nghĩ nó có giá trị một shot.

như vậy, với những gì đã nói, hãy thử thay đổi

NSError *error; 

để

NSError *error = nil; 
+1

Trong khi đó luôn luôn là lời khuyên tốt, nó không phải là hữu ích trong trường hợp này bởi vì mã của ông là kiểm tra phản ứng từ lưu và ** sau đó ** hiển thị lỗi. Trong trường hợp đó, lỗi sẽ luôn được điền. –

4

lỗi như thế này trên một dữ liệu cốt lõi tiết kiệm khi sử dụng iPhone SDK thường chỉ ra lỗi trong các phương thức ủy nhiệm NSFetchedResultsController. Cụ thể là một trong những mẩu mã ví dụ từ Apple là không đúng và thường xuyên tạo ra lỗi này. Tôi sẽ đề nghị xem xét các phương thức ủy nhiệm của bạn và so sánh chúng với mã ví dụ mới nhất vì bạn có thể thấy rằng Apple đã cập nhật mã ví dụ trong tài liệu và nếu bạn sao chép lại mã của họ, lỗi này có thể biến mất.

Hy vọng điều đó sẽ hữu ích.

+1

Bạn có liên kết đến mã ví dụ hoạt động không? – Gujamin

+0

Ví dụ được bao gồm trong Apple Documents bây giờ (3 năm sau) là chính xác. Tôi sẽ đề nghị sử dụng nó. –

+0

Liên kết xin vui lòng? Nhìn qua mã ví dụ, có một số dữ liệu cốt lõi không đề cập cụ thể đến NSFetchedResultsController vì vậy tôi không chắc chắn ví dụ nào được xác minh là đang hoạt động? – Gujamin

0

Trong trường hợp của tôi thực hiện điều này là hữu ích (petert cảm ơn của):

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller{ [self.tableView beginUpdates]; } 

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller{ 
    [self.tableView endUpdates];} 

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath{ 
switch (type) { 
    case NSFetchedResultsChangeInsert: 

     [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 
     break; 

    case NSFetchedResultsChangeDelete: 
     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 
     break; 

    case NSFetchedResultsChangeUpdate: { 

     NSString *sectionKeyPath = [controller sectionNameKeyPath]; 
     if (sectionKeyPath == nil){ 
      break; 
     } 

     [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; 

     break; 
    } 
    case NSFetchedResultsChangeMove: { 

     if (newIndexPath != nil) { 

      NSUInteger tableSectionCount = [self.tableView numberOfSections]; 
      NSUInteger frcSectionCount = [[controller sections] count]; 
      if (frcSectionCount > tableSectionCount) 
       [self.tableView insertSections:[NSIndexSet indexSetWithIndex:[newIndexPath section]] withRowAnimation:UITableViewRowAnimationNone]; 
      else if (frcSectionCount < tableSectionCount && tableSectionCount > 1) 
       [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:[indexPath section]] withRowAnimation:UITableViewRowAnimationNone]; 


      [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      [self.tableView insertRowsAtIndexPaths: [NSArray arrayWithObject:newIndexPath] 
            withRowAnimation: UITableViewRowAnimationRight]; 

     } 
     else { 
      [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[indexPath section]] withRowAnimation:UITableViewRowAnimationFade]; 
     } 
     break; 
    } 
}} 
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type{ 
switch (type) { 
    case NSFetchedResultsChangeInsert: 
     if (!((sectionIndex == 0) && ([self.tableView numberOfSections] == 1))) 
      [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 
    case NSFetchedResultsChangeDelete: 
     if (!((sectionIndex == 0) && ([self.tableView numberOfSections] == 1))) 
      [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 

     break; 
    case NSFetchedResultsChangeUpdate: 
     break; 
    case NSFetchedResultsChangeMove: 
     break; 
}} 
+0

Và cảm ơn JEFF LAMARCHE http://iphonedevelopment.blogspot.de/2010/01/navigation-based-core-data-application.html –

Các vấn đề liên quan