本文介绍了使用“controllerWillChangeContent:发送到实例的未识别的选择器”崩溃的Core Data应用程序。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个拥有2次浏览的核心资料应用程式。第一个视图列出房间,第二个列出房间中的场景。 房间页面具有编辑NavItem按钮,按下该按钮后可启用添加NavItem按钮。您可以从这里删除和添加房间。添加的房间只是在表中显示默认的新房间名称。第二个视图是所选房间中的场景列表。同样的交易在这里,你可以删除和添加场景,并添加场景只是出现在名称为新场景的表中。没有什么特别的。

I've got a core data app with 2 views. The first view lists "Rooms", the second lists "Scenes" in rooms. The Rooms page has an edit NavItem button, which when pressed enables an add NavItem button. You can delete and add rooms from here. Added rooms simply appear with a default "New Room" name in the table. The second view is a list of Scenes in the selected room. Same deal here, you can delete and add Scenes, and added Scenes simply appear in the table with the name "New Scene". Nothing special really.

我在两个视图控制器中使用 FetchedResultsController code> NSPredicate 只返回所选房间中的场景。我还使用表视图更新的 controllerWillChangeContent controllerDidChangeContent 等委托方法。

I'm using a FetchedResultsController in both view controllers, with the Scenes one having an NSPredicate to return only scenes from the selected room. I'm also using the controllerWillChangeContent, controllerDidChangeContent etc. delegate methods for the table view updates.

这一切都很好,但是通常在房间和场景中导航,然后试图删除场景时会崩溃。如果你玩了很长时间,它将不可避免地崩溃。它只会在删除场景时发生。如果按编辑按钮并删除场景并且它工作,则该编辑会话中的所有以下删除将始终工作。

This all works fine at first, but usually after navigating around rooms and scenes then trying to delete a scene it will crash. It will inevitably crash if you play around with it long enough. It only happens when deleting a scene. If you press the edit button and delete a scene and it works, then all the following deletes in that edit session will always work. It will only ever crash on the first delete of the edit session.

我得到的错误是一个奇怪的错误:

The error I get is a strange one:

此错误的第一部分有时会更改。有时它 __ NSCFType ,有时它 CALayer 。此错误仅在删除场景时发生。添加场景很好100%。

The first part of this error sometimes changes. Sometimes it's __NSCFType, sometimes it's CALayer. This error only happens when deleting Scenes. Adding Scenes is fine 100%.

我在stackoverflow上阅读了另一篇文章,表明这些错误可能来自内存管理问题。我已经双重检查的代码,并运行它通过仪器与泄漏仪器。没有泄漏。

I've read another post on stackoverflow that suggests these sorts of errors can come from memory management issues. I've double checked the code, and also run it through Instruments with the leak instrument. There are no leaks.

还有什么我可以检查吗?任何想法?

Is there anything else I can check? Any ideas?

以下是相关代码..

从ScenesTableViewController.m:

From ScenesTableViewController.m:

// used to show/hide the add button

- (void)setEditing:(BOOL)editing animated:(BOOL)animate
{
    [super setEditing:editing animated:animate];
    if(editing)
    {
        self.navigationItem.leftBarButtonItem = addButton;
    }
    else
    {
        self.navigationItem.leftBarButtonItem = nil;
    }
}

// called when the add button is pressed

- (void)addAction {
    NSEntityDescription *myContentEntity = [NSEntityDescription entityForName:@"Scene" inManagedObjectContext:managedObjectContext];
    Scene *contentToSave = [[Scene alloc] initWithEntity:myContentEntity insertIntoManagedObjectContext:managedObjectContext];
    [contentToSave setValue:@"New Scene" forKey:@"Name"];
    [parentRoom addRoomToScenesObject:contentToSave];

    NSError *error;
    if (![managedObjectContext save:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);
    }
    [contentToSave release];
}

// delegate method that's being sent unrecognised selectors

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    [self.tableView beginUpdates];
}

// cell display code

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = nil; 
    cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (!cell) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                       reuseIdentifier:CellIdentifier] autorelease]; 
        [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
    }
    [self configureCell:cell atIndexPath:indexPath]; 
    return cell;
}

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    NSManagedObject *mo = nil;
    NSString *temp = nil;
    mo = [fetchedResultsController objectAtIndexPath:indexPath];
    temp = [mo valueForKey:@"Name"];
    [[cell textLabel] setText:temp];
}

// cell editing code

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the managed object at the given index path.
        [managedObjectContext deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]];

        NSError *error;
        if (![managedObjectContext save:&error]) {
            // Update to handle the error appropriately.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            exit(-1);  // Fail
        }
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }    
}

// NSFetchedResultsController code

- (NSFetchedResultsController *)fetchedResultsController {

    if (fetchedResultsController != nil) {
        return 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:@"Scene" inManagedObjectContext:managedObjectContext];
    NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Name" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:nameDescriptor, nil];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(SceneToRoom == %@)", parentRoom];

    [fetchRequest setSortDescriptors:sortDescriptors];   
    [fetchRequest setPredicate:predicate];
    [fetchRequest setEntity:entity];

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

    [aFetchedResultsController release];
    [fetchRequest release];    
    [nameDescriptor release];
    [sortDescriptors release];

    return fetchedResultsController;
} 


推荐答案

来自具有已释放委托的 NSFetchedResultsController 。您是否已发布了 UIViewController ,但未发布相关的 NSFetchedResultsController

That error is most likely coming from a NSFetchedResultsController that has a released delegate. Do you have a UIViewController that you released and didn't release the associated NSFetchedResultsController?

这篇关于使用“controllerWillChangeContent:发送到实例的未识别的选择器”崩溃的Core Data应用程序。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 12:52