2010-12-22 36 views
0

我對iOS上的Core Data相對較新,但我認爲我已經越來越好了。然而,在我的一個應用程序中,我一直在經歷一次奇怪的崩潰,並且一直未能弄清楚。嘗試從25 NSFetchedResultsController獲取NSManagedObject後崩潰?

我在覈心數據中有大約40個對象,呈現在UITableView中。當單擊單元格時,會出現一個UIActionSheet,向用戶顯示一個UIActionSheet,其中包含與所選單元格相關的選項。所以,我可以參考選擇的對象,我在我的頭被稱爲「lastSelection」聲明NSIndexPath並執行以下操作時,UIActionSheet提出:

// Each cell has a tag based on its row number (i.e. first row has tag 0) 
lastSelection = [NSIndexPath indexPathForRow:[sender tag] inSection:0]; 
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:lastSelection]; 
BOOL onDuty = [[managedObject valueForKey:@"onDuty"] boolValue]; 
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Status" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil]; 
if(onDuty) { 
    [actionSheet addButtonWithTitle:@"Off Duty"]; 
} else { 
    [actionSheet addButtonWithTitle:@"On Duty"]; 
} 
    actionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque; 

// Override the typical UIActionSheet behavior by presenting it overlapping the sender's frame. This makes it more clear which cell is selected. 
CGRect senderFrame = [sender frame]; 
CGPoint point = CGPointMake(senderFrame.origin.x + (senderFrame.size.width/2), senderFrame.origin.y + (senderFrame.size.height/2)); 
CGRect popoverRect = CGRectMake(point.x, point.y, 1, 1); 
    [actionSheet showFromRect:popoverRect inView:[sender superview] animated:NO]; 
    [actionSheet release]; 

當UIActionSheet被解僱一個按鈕,下面的代碼是所謂:

- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex { 
// Set status based on UIActionSheet button pressed 
if(buttonIndex == -1) { 
    return; 
} 

NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:lastSelection]; 

if([actionSheet.title isEqualToString:@"Status"]) { 
    if([[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:@"On Duty"]) { 
    [managedObject setValue:[NSNumber numberWithBool:YES] forKey:@"onDuty"]; 
    [managedObject setValue:@"onDuty" forKey:@"status"]; 
    } else { 
    [managedObject setValue:[NSNumber numberWithBool:NO] forKey:@"onDuty"]; 
    [managedObject setValue:@"offDuty" forKey:@"status"]; 
    } 
} 

NSError *error; 
[self.managedObjectContext save:&error]; 

[tableView reloadData]; 
} 

這可能不是最有效的代碼(對不起,我是新!),但它確實工作。也就是說,列表中的前25個項目。選擇第26項或超越,UIActionSheet會出現,但如果它與一個按鈕被解僱,我收到了各種各樣的錯誤,包括以下內容中的任何一個:如果我註釋掉NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:lastSelection];它不」

[__NSCFArray section]: unrecognized selector sent to instance 0x4c6bf90 

Program received signal: 「EXC_BAD_ACCESS」 

[_NSObjectID_48_0 section]: unrecognized selector sent to instance 0x4c54710 

[__NSArrayM section]: unrecognized selector sent to instance 0x4c619a0 

[NSComparisonPredicate section]: unrecognized selector sent to instance 0x6088790 

[NSKeyPathExpression section]: unrecognized selector sent to instance 0x4c18950 

我再也沒有碰到過,所以我相信它有一些事情要做。誰能提供任何見解?請讓我知道是否需要包含任何其他信息。謝謝!

編輯:有趣的是,我fetchedResultsController代碼每次返回一個不同的對象。這是預期的,還是這可能是我的問題的原因?代碼如下所示:

- (NSFetchedResultsController *)fetchedResultsController { 
    /* 
    Set up the fetched results controller. 
    */ 
    // Create the fetch request for the entity. 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    // Edit the entity name as appropriate. 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    // Set the batch size to a suitable number. 
    [fetchRequest setFetchBatchSize:80]; 

    // Edit the sort key as appropriate. 
NSString *sortKey; 
BOOL ascending; 
if(sortControl.selectedSegmentIndex == 0) { 
    sortKey = @"startTime"; 
    ascending = YES; 
} else if(sortControl.selectedSegmentIndex == 1) { 
    sortKey = @"name"; 
    ascending = YES; 
} else { 
    sortKey = @"onDuty"; 
    ascending = NO; 
} 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:ascending]; 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 

    [fetchRequest setSortDescriptors:sortDescriptors]; 

    // Edit the section name key path and cache name if appropriate. 
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"]; 
    aFetchedResultsController.delegate = self; 
    self.fetchedResultsController = aFetchedResultsController; 

    [aFetchedResultsController release]; 
    [fetchRequest release]; 
    [sortDescriptor release]; 
[sortDescriptors release]; 

    NSError *error = nil; 
    if (![fetchedResultsController_ performFetch:&error]) { 
     /* 
     Replace this implementation with code to handle the error appropriately. 

     abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 
     */ 
     //NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 

    return fetchedResultsController_; 
} 

發生這種情況時,我設置斷點:

(gdb) po [self fetchedResultsController] 
<NSFetchedResultsController: 0x61567c0> 
(gdb) po [self fetchedResultsController] 
<NSFetchedResultsController: 0x4c83630> 

回答

0

它的概率是self.fetchedResultsController指向錯誤的內存位置的情況。您需要檢查對象是否已被保留。

+0

我應該在哪裏做?在我的代碼中,我有NSFetchedResultsController * aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@「Root」]; - 我嘗試添加一個保留到這,但它沒有奏效。 – Jeremy 2010-12-23 01:08:42

+0

我更新了我的問題 - 希望這可能有助於解決這個問題。我非常感謝! – Jeremy 2010-12-23 01:52:33

0

想通了!看起來這是一個自動釋放對象的問題。

當我打開NSZombieEnabled,我得到這個:

*** -[NSIndexPath section]: message sent to deallocated instance 0xa674530 

我只是改變lastSelection = [NSIndexPath indexPathForRow:[sender tag] inSection:0];lastSelection = [[NSIndexPath indexPathForRow:[sender tag] inSection:0] retain];並照顧它。