本文介绍了NSFetchedResultsController不调用controllerDidChangeContent:更新后,未获取NSManagedObject的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我填充并 $ c> save:。I populate and save: an initial NSManagedObjectContextsetup an NSFetchedResultsController with a different NSManagedObjectContext, which filters on a boolean "show" attribute.Finally update "show" on yet another NSManagedObjectContext and save:. 我希望这会导致我的 NSFetchedResultsController 调用 NSFetchedResultsControllerDelegate 的 controllerDidChangeContent:。我从来没有得到那个电话。 NSFetchedResultsController具有谓词,忽略从不同NSManagedObjectContext 合并的更改 接受答案表示除了 controllerDidChangeContent:,我应该得到一个 NSManagedObjectContextObjectsDidChangeNotification ,但我没有收到。I expect that this should cause my NSFetchedResultsController to call NSFetchedResultsControllerDelegate's controllerDidChangeContent:. I never get that call. NSFetchedResultsController with predicate ignores changes merged from different NSManagedObjectContext's accepted answer indicates that in addition to controllerDidChangeContent:, I should get an NSManagedObjectContextObjectsDidChangeNotification, but I don't receive that either.下面提供了一个完整的代码示例, on github 。 我已向苹果公司提交了雷达。A complete code example is included below and on github. I've filed a radar with Apple.@interface HJBFoo : NSManagedObject@property (nonatomic, retain) NSString *name;@property (nonatomic, retain) NSNumber *show;@end@interface HJBAppDelegate () <NSFetchedResultsControllerDelegate>@property (nonatomic, strong) NSPersistentStoreCoordinator *persistentStoreCoordinator;@property (nonatomic, strong) NSManagedObjectContext *initialManagedObjectContext;@property (nonatomic, strong) NSManagedObjectContext *fetchedResultsControllerManagedObjectContext;@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;@end@implementation HJBAppDelegate#pragma mark - UIApplicationDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor]; self.window.rootViewController = [UIViewController new]; NSAttributeDescription *nameAttributeDescription = [NSAttributeDescription new]; [nameAttributeDescription setAttributeType:NSStringAttributeType]; [nameAttributeDescription setIndexed:NO]; [nameAttributeDescription setOptional:NO]; [nameAttributeDescription setName:@"name"]; NSAttributeDescription *showAttributeDescription = [NSAttributeDescription new]; [showAttributeDescription setAttributeType:NSBooleanAttributeType]; [showAttributeDescription setIndexed:YES]; [showAttributeDescription setOptional:NO]; [showAttributeDescription setName:@"show"]; NSEntityDescription *fooEntityDescription = [NSEntityDescription new]; [fooEntityDescription setManagedObjectClassName:@"HJBFoo"]; [fooEntityDescription setName:@"HJBFoo"]; [fooEntityDescription setProperties:@[ nameAttributeDescription, showAttributeDescription, ]]; NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel new]; [managedObjectModel setEntities:@[ fooEntityDescription, ]]; self.persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel]; NSError *error = nil; if ([self.persistentStoreCoordinator addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:&error]) { self.initialManagedObjectContext = [NSManagedObjectContext new]; [self.initialManagedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; HJBFoo *foo1 = [NSEntityDescription insertNewObjectForEntityForName:@"HJBFoo" inManagedObjectContext:self.initialManagedObjectContext]; foo1.name = @"1"; foo1.show = @YES; HJBFoo *foo2 = [NSEntityDescription insertNewObjectForEntityForName:@"HJBFoo" inManagedObjectContext:self.initialManagedObjectContext]; foo2.name = @"2"; foo2.show = @NO; error = nil; if ([self.initialManagedObjectContext save:&error]) { NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"HJBFoo"]; [fetchRequest setReturnsObjectsAsFaults:NO]; error = nil; NSArray *initialFoos = [self.initialManagedObjectContext executeFetchRequest:fetchRequest error:&error]; if (initialFoos) { NSLog(@"Initial: %@", initialFoos); self.fetchedResultsControllerManagedObjectContext = [NSManagedObjectContext new]; [self.fetchedResultsControllerManagedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; NSFetchRequest *shownFetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"HJBFoo"]; [shownFetchRequest setPredicate:[NSPredicate predicateWithFormat:@"show == YES"]]; [shownFetchRequest setSortDescriptors:@[ [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES], ]]; self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:shownFetchRequest managedObjectContext:self.fetchedResultsControllerManagedObjectContext sectionNameKeyPath:nil cacheName:nil]; self.fetchedResultsController.delegate = self; error = nil; if ([self.fetchedResultsController performFetch:&error]) { NSLog(@"Initial fetchedObjects: %@", [self.fetchedResultsController fetchedObjects]); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContext2ObjectsDidChange:) name:NSManagedObjectContextObjectsDidChangeNotification object:self.fetchedResultsControllerManagedObjectContext]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void){ NSManagedObjectContext *managedObjectContext3 = [NSManagedObjectContext new]; [managedObjectContext3 setPersistentStoreCoordinator:self.persistentStoreCoordinator]; NSFetchRequest *foo2FetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"HJBFoo"]; [foo2FetchRequest setFetchLimit:1]; [foo2FetchRequest setPredicate:[NSPredicate predicateWithFormat:@"name == %@", @"2"]]; NSError *editingError = nil; NSArray *editingFoos = [managedObjectContext3 executeFetchRequest:foo2FetchRequest error:&editingError]; if (editingFoos) { HJBFoo *editingFoo2 = [editingFoos objectAtIndex:0]; editingFoo2.show = @YES; editingError = nil; if ([managedObjectContext3 save:&editingError]) { NSLog(@"Save succeeded. Expected (in order) managedObjectContextDidSave, controllerDidChangeContent, managedObjectContext2ObjectsDidChange"); } else { NSLog(@"Editing save failed: %@ %@", [error localizedDescription], [error userInfo]); } } else { NSLog(@"Editing fetch failed: %@ %@", [error localizedDescription], [error userInfo]); } }); } else { NSLog(@"Failed initial fetch: %@ %@", [error localizedDescription], [error userInfo]); } } else { NSLog(@"Failed to performFetch: %@ %@", [error localizedDescription], [error userInfo]); } } else { NSLog(@"Failed to save initial state: %@ %@", [error localizedDescription], [error userInfo]); } } else { NSLog(@"Failed to add persistent store: %@ %@", [error localizedDescription], [error userInfo]); } [self.window makeKeyAndVisible]; return YES;}#pragma mark - NSFetchedResultsControllerDelegate- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { NSLog(@"controllerDidChangeContent: %@", [self.fetchedResultsController fetchedObjects]);}#pragma mark - notifications- (void)managedObjectContextDidSave:(NSNotification *)notification { NSManagedObjectContext *managedObjectContext = [notification object]; if (([managedObjectContext persistentStoreCoordinator] == self.persistentStoreCoordinator) && (managedObjectContext != self.fetchedResultsControllerManagedObjectContext)) { NSLog(@"managedObjectContextDidSave: %@", notification); [self.fetchedResultsControllerManagedObjectContext mergeChangesFromContextDidSaveNotification:notification]; }}- (void)managedObjectContext2ObjectsDidChange:(NSNotification *)notification { NSLog(@"managedObjectContext2ObjectsDidChange: %@", notification);}@end@implementation HJBFoo@dynamic name;@dynamic show;@end推荐答案在我看来,从 NSFetchedResultsController应用修复/解决方法谓词忽略从不同的NSManagedObjectContext合并的更改也解决了您的问题。 managedObjectContextDidSave 方法将如下所示:It seems to me that applying the fix/workaround from NSFetchedResultsController with predicate ignores changes merged from different NSManagedObjectContext solves your problem as well. Your managedObjectContextDidSave method would then look like this:- (void)managedObjectContextDidSave:(NSNotification *)notification { NSManagedObjectContext *managedObjectContext = [notification object]; if (([managedObjectContext persistentStoreCoordinator] == self.persistentStoreCoordinator) && (managedObjectContext != self.fetchedResultsControllerManagedObjectContext)) { NSLog(@"managedObjectContextDidSave: %@", notification); // Fix/workaround from http://stackoverflow.com/questions/3923826/nsfetchedresultscontroller-with-predicate-ignores-changes-merged-from-different/3927811#3927811 for(NSManagedObject *object in [[notification userInfo] objectForKey:NSUpdatedObjectsKey]) { [[self.fetchedResultsControllerManagedObjectContext objectWithID:[object objectID]] willAccessValueForKey:nil]; } [self.fetchedResultsControllerManagedObjectContext mergeChangesFromContextDidSaveNotification:notification]; }},NSLog输出看起来像预期的那样:and the NSLog output looks as expected:Initial: ( "<HJBFoo: 0xaa19670> (entity: HJBFoo; id: 0xaa1afd0 <x-coredata://07E97098-E32D-45F6-9AB4-F9DAB9B0AC1A/HJBFoo/p2> ; data: {\n name = 1;\n show = 1;\n})", "<HJBFoo: 0xaa1a200> (entity: HJBFoo; id: 0xaa1af50 <x-coredata://07E97098-E32D-45F6-9AB4-F9DAB9B0AC1A/HJBFoo/p1> ; data: {\n name = 2;\n show = 0;\n})")Initial fetchedObjects: ( "<HJBFoo: 0x74613f0> (entity: HJBFoo; id: 0xaa1afd0 <x-coredata://07E97098-E32D-45F6-9AB4-F9DAB9B0AC1A/HJBFoo/p2> ; data: <fault>)")managedObjectContextDidSave: NSConcreteNotification 0xaa1f480 {name = NSManagingContextDidSaveChangesNotification; object = <NSManagedObjectContext: 0xaa1ed90>; userInfo = { inserted = "{(\n)}"; updated = "{(\n <HJBFoo: 0xaa1f2d0> (entity: HJBFoo; id: 0xaa1af50 <x-coredata://07E97098-E32D-45F6-9AB4-F9DAB9B0AC1A/HJBFoo/p1> ; data: {\n name = 2;\n show = 1;\n})\n)}";}}Save succeeded. Expected (in order) managedObjectContextDidSave, controllerDidChangeContent, managedObjectContext2ObjectsDidChangecontrollerDidChangeContent: ( "<HJBFoo: 0x74613f0> (entity: HJBFoo; id: 0xaa1afd0 <x-coredata://07E97098-E32D-45F6-9AB4-F9DAB9B0AC1A/HJBFoo/p2> ; data: {\n name = 1;\n show = 1;\n})", "<HJBFoo: 0xaa1f9c0> (entity: HJBFoo; id: 0xaa1af50 <x-coredata://07E97098-E32D-45F6-9AB4-F9DAB9B0AC1A/HJBFoo/p1> ; data: {\n name = 2;\n show = 1;\n})")managedObjectContext2ObjectsDidChange: NSConcreteNotification 0xaa1fbb0 {name = NSObjectsChangedInManagingContextNotification; object = <NSManagedObjectContext: 0x745fa50>; userInfo = { managedObjectContext = "<NSManagedObjectContext: 0x745fa50>"; refreshed = "{(\n <HJBFoo: 0xaa1f9c0> (entity: HJBFoo; id: 0xaa1af50 <x-coredata://07E97098-E32D-45F6-9AB4-F9DAB9B0AC1A/HJBFoo/p1> ; data: {\n name = 2;\n show = 1;\n})\n)}";}}因此,会发生以下情况:So the following things happen: 在背景上下文 managedObjectContext3 中进行更改并保存。 您收到 NSManagedObjectContextDidSaveNotification 和 managedObjectContextDidSave:被调用。Changes are made in the "background" context managedObjectContext3 and saved.You receive a NSManagedObjectContextDidSaveNotification and managedObjectContextDidSave: is called. This notification contains the object that was updated in the background context.Calling[self.fetchedResultsControllerManagedObjectContext mergeChangesFromContextDidSaveNotification:notification];现在会不执行任何操作,因为更新的对象尚未加载进入 fetchedResultsControllerManagedObjectContext 或者是一个错误。now would not do anything, because the updated object has not been loaded into the fetchedResultsControllerManagedObjectContext or is a fault. In particular, this context would not post a NSManagedObjectContextObjectsDidChangeNotification and the fetched results controller would not update.呼叫[self.fetchedResultsControllerManagedObjectContext mergeChangesFromContextDidSaveNotification:notification];之后,实际更新 fetchedResultsControllerManagedObjectContext 这篇关于NSFetchedResultsController不调用controllerDidChangeContent:更新后,未获取NSManagedObject的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 阿里云证书,YYDS!
05-24 22:13