2010-12-29 35 views
10

Đây là từ mã mẫu của Apple:Làm cách nào để xử lý lỗi tìm nạp NSFetchedResultsController?

if (![fetchedResultsController_ performFetch:&error]) { 
    /* 
     Replace this implementation with code to handle the error appropriately. 
     ... 
     If it is not possible to recover from the error, ... 
     */ 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    abort(); 
} 

tôi tự hỏi liệu nó có thực sự cần thiết để luôn chấm dứt ứng dụng? Làm cách nào để "thay thế việc triển khai này bằng mã để xử lý lỗi một cách thích hợp"? Và làm cách nào để bạn "khôi phục từ lỗi"?

Bất kỳ lời đề nghị sẽ được đánh giá, Fabian

+2

Lệnh 'hủy bỏ()' gọi là có một chiến thuật sợ hãi. – BoltClock

+1

Dù sao nó sẽ phụ thuộc vào bộ điều khiển kết quả tìm nạp đang tìm kiếm. Điều đó có nghĩa là đối với những thứ khác nhau trong ứng dụng của bạn, bạn sẽ muốn xử lý lỗi khác nhau. Câu hỏi của bạn về * chính xác những gì cần làm * với đối tượng 'NSError' đó vẫn hợp lệ, vì vậy +1 – BoltClock

+0

Tôi có xu hướng nhận được cảnh báo trên màn hình hiển thị bản địa hóa của NSError, để người dùng có điều gì đó báo cáo về hỗ trợ kỹ thuật. –

Trả lời

7

Vâng, rõ ràng không ai đã khác (tốt hơn?) Giải pháp, vì vậy đây là cách tiếp cận của tôi:

Trong AppController tôi thêm một trường hợp biến errorString và phương pháp này:

- (void)presentCoreDataError:(NSError *)error 
        withText:(NSString *)text 
{ 
    NSMutableString *localErrorString = [[NSMutableString alloc] init]; 

    [localErrorString appendFormat:@"Failed to %@: %@", text, [error localizedDescription]]; 

    NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey]; 
    if(detailedErrors != nil && [detailedErrors count] > 0) { 
     for(NSError* detailedError in detailedErrors) { 
      [localErrorString appendFormat:@"- Detail: %@", [detailedError userInfo]]; 
     } 
    } else { 
     [localErrorString appendFormat:@"- %@", [error userInfo]]; 
    } 

    UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"Failed to %@", text] 
                message:@"Please send a report to the developer." 
                delegate:self 
              cancelButtonTitle:@"Cancel" 
              otherButtonTitles:@"Send Report", nil] autorelease]; 
    [alert show]; 

    self.errorString = localErrorString; 
    [localErrorString release]; 
} 

các UIAlertView đại biểu sẽ hiển thị một MFMailComposeViewController với errorString dùng font courier mát mẻ :) nếu "Gửi báo cáo" được khai thác. Nếu không nó gọi abort():

- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{ 
    if (buttonIndex == 1) {  // Send Report 
     MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init]; 
     picker.mailComposeDelegate = self; 
     NSArray *toRecipients = [NSArray arrayWithObject:@"[email protected]"]; 
     [picker setToRecipients:toRecipients]; 
     [picker setSubject:@"Error Report"]; 
     [picker setMessageBody:[NSString stringWithFormat:@"The application crashed with the following error:<br><br><FONT FACE=%@> %@ </FONT>", 
           @"courier", errorString] 
         isHTML:YES]; 

     [navigationController presentModalViewController:picker animated:YES]; 
     [picker release]; 
    } else { 
     abort(); 
    } 
} 

MFMailComposeViewControllerDelegate màn hình một giây UIAlertView chỉ với một nút (rõ ràng là nút có chỉ số 0, vì vậy nó sẽ gọi abort()):

- (void)mailComposeController:(MFMailComposeViewController *)controller 
      didFinishWithResult:(MFMailComposeResult)result 
         error:(NSError *)error 
{ 
    [navigationController dismissModalViewControllerAnimated:YES]; 

    NSMutableString *messageString = [[NSMutableString alloc] init]; 

    if (result == MFMailComposeResultSent) { 
     [messageString appendFormat:@"Thanks! "]; 
    } 

    [messageString appendFormat:@"The application has to quit now."]; 
    UIAlertView *abortAlert = [[[UIAlertView alloc] initWithTitle:nil 
                  message:messageString 
                 delegate:self 
               cancelButtonTitle:@"OK" 
               otherButtonTitles:nil] autorelease]; 

    [abortAlert show]; 

    [messageString release]; 
} 
+0

Bạn đã sử dụng giải pháp này trong sản xuất? Ngoài ra, bạn đã bao giờ nhận được bất kỳ email nào chưa? – abellina

+0

Tôi đã sử dụng nó trong sản xuất và tôi đã nhận được hai e-mail. – fabian789

+1

@ fabian789 Vẫn còn nhiều năm sau, cảm ơn! Bạn cũng có thể muốn sử dụng '[MFMailComposeViewController canSendMail]' để xác định xem thiết bị có được cấu hình để gửi email hay không và cung cấp thông báo cảnh báo dự phòng nếu không, trước khi khởi tạo 'MFMailComposeViewController'. – JWK

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