核心数据委托方法不止一次被调用

时间:2012-09-06 16:40:11

标签: ios5 core-data xmpp nsfetchedresultscontroller nsmanagedobjectcontext

我正在使用XMPP创建一个FBChat。我为coredata和fetchedResults创建了单独的类。

CoreDataClass:

@implementation CoreDataClass

@synthesize managedObjectContext = __managedObjectContext;
@synthesize managedObjectModel = __managedObjectModel;
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;


- (NSManagedObjectContext *)managedObjectContext
{

    if (__managedObjectContext != nil)
    {
        return __managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil)
    {
        __managedObjectContext = [[NSManagedObjectContext alloc] init] ;
        [__managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return __managedObjectContext;
}


- (NSManagedObjectModel *)managedObjectModel
{
    if (__managedObjectModel != nil)
    {
        return __managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Chat" withExtension:@"momd"];
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return __managedObjectModel;
}


- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
        return __persistentStoreCoordinator;
    }
    AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSURL *storeURL = [[delegate applicationDocumentsDirectory] URLByAppendingPathComponent:@"FacebookChat.sqlite"];
    NSError *error = nil;
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];



    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
    {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    

    return __persistentStoreCoordinator;
}
- (void)saveContext
{
    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil)
    {
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error])
        {
                       NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        } 
    }
}

FetchedControlClass:

@implementation FetchedControllClass
@synthesize fetchedResultsController;

#pragma mark Fetched Results

- (NSFetchedResultsController *)fetchedResultsController
{
    CoreDataClass *coreDataObject=[[CoreDataClass alloc]init];

    if (fetchedResultsController != nil) {
        return fetchedResultsController;
    }


    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Conversation" inManagedObjectContext:coreDataObject.managedObjectContext];
    [fetchRequest setEntity:entity];
    [fetchRequest setFetchBatchSize:20];
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"facebookName" ascending:YES];

    NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];    
    [fetchRequest setSortDescriptors:sortDescriptors];
    [sortDescriptor release];

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataObject.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"] ;
    [fetchRequest release];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;
    [aFetchedResultsController release];
    NSError *error = nil;
    if (![self.fetchedResultsController performFetch:&error]) {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
    [coreDataObject release];
    return fetchedResultsController;
}    

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    AlertListVC *alertListObject=[[AlertListVC alloc]initWithNibName:@"AlertListVC" bundle:nil];

    [alertListObject.tableView beginUpdates];
    [alertListObject release];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    AlertListVC *alertListObject=[[AlertListVC alloc]initWithNibName:@"AlertListVC" bundle:nil];


    switch(type) {
        case NSFetchedResultsChangeInsert:
            [alertListObject.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [alertListObject.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
    [alertListObject release];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{
    AlertListVC *alertListObject=[[AlertListVC alloc]initWithNibName:@"AlertListVC" bundle:nil];

    UITableView *tableView = alertListObject.tableView;

    switch(type) {
        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [alertListObject configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
    [alertListObject release];
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    AlertListVC *alertListObject=[[AlertListVC alloc]initWithNibName:@"AlertListVC" bundle:nil];
    [alertListObject.tableView endUpdates]; 
    [alertListObject release];

}

我在MainChatClass中为两个类创建了对象,并将coredata中的对话添加到ConversationClass

Conversation *conversation = (Conversation *)[NSEntityDescription
                                                          insertNewObjectForEntityForName:@"Conversation"
                                                          inManagedObjectContext:coreDataClassObject.managedObjectContext];

我能够获得fetchedResults但是 问题是: Coredata方法正在被解决两次(因此文件创建了两次)。如果我选​​择要聊天的朋友,那么应用程序将崩溃。我使用僵尸来跟踪问题。它显示一些错误 负责的来电者: 1. [MainChatClass tableView:didSelectRowAtIndexPath] 2. [NSFetchedResultsController(私有方法)_managedObjectContextDidChange]

我已尝试多次,但仍然遇到这些方法的错误。 如果有任何人有这个想法,那么请帮助我。 提前致谢

1 个答案:

答案 0 :(得分:0)

在每个FRC委托方法中,您创建一个新的alertListObject。这是没有意义的。您必须将更新消息发送到现有的表视图。

发生崩溃是因为alertListObject.tableView对于新创建的视图控制器是nil