這是一個奇怪的問題。核心數據不會對已更改的謂詞做出反應
在我的視圖控制器SpieleOrtTVC
我將介紹實體Spiel
的對象的子集。每次調用視圖控制器時,都應根據用戶在呈現視圖控制器中的選擇顯示不同的子集。
這適用於每次第一次調用視圖控制器。取決於用戶的選擇,獲取的證件會被交給新的視圖控制器,並且正確地到達那裏,正如NSLog證明的那樣。顯示的結果和數據是經過精心設計的。
但是,當視圖控制器被第二次或第三次調用時,正確的獲取條件也被傳遞給視圖控制器,但是,獲取結果對應於之前執行的獲取。
這是代碼。 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;
(只是一個屬性,無吸氣劑或setter方法等,自動合成)
這是我對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
而且這是在下次調用的結果,不同的用戶選擇:
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
這清楚地表明,不同的選擇標準是正確服用從用戶的交互中傳遞給新的視圖控制器。特別是獲取請求相應地獲取其謂詞集,但結果在兩種情況下都是相同的。 (此處示例中使用的時間戳對所有對象都是唯一的)
這裏有什麼問題?
我很高興分享到更多的代碼。告訴我你認爲與這個問題有關的東西。
如果這是很重要的:iOS版7.1.1,設備(iPhone 4,4S,5,iPad的迷你 - 都是一樣的)上運行時,Xcode 5.1.1
(我有一個方便的解決方法,但出於好奇,我想知道問題是什麼。)
它可能與緩存有關。嘗試'cacheName:nil'來創建抓取的結果控制器。 –
@MartinR,好主意。與此同時,我觀察到另一個影響。我有另一個視圖控制器,顯示所有這些實體對象的超集。當我去的時候,一切都很好。第一個子集視圖(與上述問題相關的視圖)工作正常,所有後續調用如上所述。當我首先使用子視圖控制器時,那麼顯示超集的視圖控制器只會顯示相同的子集。 –
是的,沒有給出它的緩存名稱似乎工作。感謝提示。您是否認爲這是核心數據中的錯誤? –