核心数据委托方法被多次调用
Posted
技术标签:
【中文标题】核心数据委托方法被多次调用【英文标题】:core data delegate methods are getting called more than once 【发布时间】:2012-09-06 16:40:10 【问题描述】:我正在使用 XMPP 创建一个 FBChat。我为 coredata 和 fetchedResults 创建了单独的类。
核心数据类:
@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】:在每个 FRC 委托方法中,您创建一个新的 alertListObject
。这是没有意义的。您必须将更新消息发送到您现有的表格视图。
发生崩溃是因为 alertListObject.tableView
是 nil
用于新创建的视图控制器。
【讨论】:
感谢您的回答。我已将 fetch 控制器委托方法放入主类并解决了问题。 @Anand:我很高兴听到这个消息。如果我的回答有帮助,您应该通过单击答案左侧的复选标记“接受”它。以上是关于核心数据委托方法被多次调用的主要内容,如果未能解决你的问题,请参考以下文章
UIPopoverController 委托委托方法未被调用
Facebook fbDidLogin 在 [facebook authorize:permissions] 之后被多次调用