核心数据不会对已更改的谓词做出反应

这是一个奇怪的问题。

在我的视图控制器SpieleOrtTVC我将展示Spiel实体的一个子集。 每次调用视图控制器时,都应该根据用户在视图控制器中的select来显示不同的子集。

这对于每次第一次调用视图控制器都很有效。 取决于用户的select,抓取文件被移交给新的视图控制器,并正确地到达那里,正如NSLogcertificate的那样。 显示的结果和数据也是如此。

但是当视图控制器被第二次或第三次调用时,那么正确的获取条件也会被传递给视图控制器,但是这个获取结果对应于之前执行的获取。

这是代码。 SpieleOrtTVC被称为地图标注。 所选对象的名称恰好在注释标题中,被移交给新近实现的SpieleOrtTVC。

调用视图控制器与地图:

 - (void)mapView:(MKMapView *)mv annotationView:(MKAnnotationView *)pin calloutAccessoryControlTapped:(UIControl *)control { SpieleOrtTVC *detailViewController = [self.storyboard instantiateViewControllerWithIdentifier:STORYBOARD_ID_SPIELE_ORT]; MKPointAnnotation *theAnnotation = (MKPointAnnotation *) pin.annotation; NSLog(@"the Annotation %@",theAnnotation.title); detailViewController.ortName = theAnnotation.title; detailViewController.stadionName = theAnnotation.subtitle; [self presentViewController:detailViewController animated:YES completion:nil]; } 

SpieleOrteTVC.h:

 @property (strong, nonatomic) NSString *ortName; @property (strong, nonatomic) NSString *stadionName; 

(只是一个财产,没有获得者或二传手等自动合成)

这是我对SpieleOrteTVC.m怀疑的一段代码:

 - (NSManagedObjectContext *) managedObjectContext { if (! _managedObjectContext) { _managedObjectContext = [(AppDelegate*) [[UIApplication sharedApplication] delegate] managedObjectContext]; } return _managedObjectContext; } - (NSFetchedResultsController *)fetchedResultsController { if (_fetchedResultsController != nil) { return _fetchedResultsController; } NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; // Edit the entity name as appropriate. NSEntityDescription *entity = [NSEntityDescription entityForName:[self entityName] inManagedObjectContext:self.managedObjectContext]; [fetchRequest setEntity:entity]; // Set the batch size to a suitable number. [fetchRequest setFetchBatchSize:20]; // Edit the sort key as appropriate. NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:[self sortDescriptorString] ascending:[self sortAscending]]; NSArray *sortDescriptors = @[sortDescriptor]; [fetchRequest setSortDescriptors:sortDescriptors]; [fetchRequest setPredicate:[self predicate]]; // 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:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"]; aFetchedResultsController.delegate = self; self.fetchedResultsController = aFetchedResultsController; NSError *error = nil; if (![self.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. NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } NSLog(@"request: %@", fetchRequest); for (NSManagedObject *mo in [_fetchedResultsController fetchedObjects]) { NSLog(@"fetched: %@", [mo valueForKey:ATTRIB_ANSTOSS]); } - (NSString *) entityName { return ENTITY_SPIEL; } - (NSString *) sortDescriptorString{ return ATTRIB_ANSTOSS; } - (NSPredicate *) predicate { return [NSPredicate predicateWithFormat:@"(spielOrt.name == %@)", self.ortName]; } - (BOOL) sortAscending { return YES; } 

首次通话的输出:

 2014-05-11 13:49:16.209 myApp[2745:60b] the Annotation Porto Alegre 2014-05-11 13:49:21.937 myApp[2745:60b] request: <NSFetchRequest: 0x18c0c960> (entity: Spiel; predicate: (spielOrt.name == "Porto Alegre"); sortDescriptors: (( "(anstoss, ascending, compare:)" )); batch size: 20; type: NSManagedObjectResultType; ) 2014-05-11 13:49:21.955 myApp[2745:60b] fetched: 2014-06-15 19:00:51 +0000 2014-05-11 13:49:21.957 myApp[2745:60b] fetched: 2014-06-18 16:00:52 +0000 2014-05-11 13:49:21.959 myApp[2745:60b] fetched: 2014-06-22 19:00:51 +0000 2014-05-11 13:49:21.960 myApp[2745:60b] fetched: 2014-06-25 16:00:51 +0000 2014-05-11 13:49:21.962 myApp[2745:60b] fetched: 2014-06-30 20:00:04 +0000 

这是下一次调用的结果,用户select不同:

 2014-05-11 13:50:25.654 myApp[2745:60b] the Annotation Fortaleza 2014-05-11 13:50:25.675 myApp[2745:60b] request: <NSFetchRequest: 0x18c6c0e0> (entity: Spiel; predicate: (spielOrt.name == "Fortaleza"); sortDescriptors: (( "(anstoss, ascending, compare:)" )); batch size: 20; type: NSManagedObjectResultType; ) 2014-05-11 13:50:25.681 myApp[2745:60b] fetched: 2014-06-15 19:00:51 +0000 2014-05-11 13:50:25.683 myApp[2745:60b] fetched: 2014-06-18 16:00:52 +0000 2014-05-11 13:50:25.684 myApp[2745:60b] fetched: 2014-06-22 19:00:51 +0000 2014-05-11 13:50:25.686 myApp[2745:60b] fetched: 2014-06-25 16:00:51 +0000 2014-05-11 13:50:25.687 myApp[2745:60b] fetched: 2014-06-30 20:00:04 +0000 

它清楚地表明,从用户的交互中正确地采取不同的select标准,并传递给新的视图控制器。 特别是获取请求相应地得到它的谓词集,但是结果在两种情况下都是相同的。 (这里用于示例的时间戳对于所有对象都是唯一的)

这里有什么问题?

我很高兴分享更多的代码。 只要告诉我你认为与这个问题有关的东西。

如果这是重要的:在设备上运行的iOS 7.1.1(iPhone 4,4S,5,iPad mini – 都一样),Xcode 5.1.1

(我有一个方便的方法,但出于好奇,我想知道问题是什么。)

NSFetchedResultsController参考:

重要提示:如果您正在使用caching,则在更改任何获取请求,谓词或其sorting描述符之前,必须调用deleteCacheWithName: 除非将cacheName设置为nil否则不得重复使用相同的提取结果控制器进行多个查询。

所以在你的情况下,问题是FRC重新使用为其他谓词创build的caching。 在创build新的FRC之前,不要使用caching( cacheName:nil )或删除caching。 在你的情况下,caching可能没有多大意义。