NSPredicate cause update editing to return NSFetchedResultsChangeDelete not NSFetchedResultsChangeUpdate
I have predicate inside of - (NSFetchedResultsController *)fetchedResultsController
in a standard way starting from the CoreDataBook example.
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"state=%@ && date >= %@ && date < %@", @"1",fromDate,toDate];
[fetchRequest setPredicate:predicate];
This works fine however when editing an item, it returns with NSFetchedResultsChangeDelete not Update. When the main view returns, it is missing the item. If I restart the simulator the delete was not saved and the correct editing result is shown the the predicate working correctly.
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
I can confirm the behavior by commenting out the two predicate lines ONLY and then all works as it should correctly returning with the full set after editing and calling NSFetchedResultsChangeUpdate instead of NSFetchedResultsChangeDelete.
I have read http://matte开发者_运维知识库ocaldari.it/2009/11/multiple-contexts-controllers-delegates-and-coredata-bug who reports similar behavior but I have not found a work around to my problem.
I meet this problem too. The root reason is caused by setting the value of attribute in the NSPredicate format string with a wrong type.
For this problem may be the attribute of "state
" has a Number type, like "Integer 32
". But the code above passed a NSString to it(@"1"
), just change it to a NSNumber(@1
), will fixed the problem.
Matthew Weiss finally fixed the problem by using fetch request template. I think the "state
" is checked in the template which doesn't have the type problem. And only fromDate and toDate are passed by subs.
Sorry it has been awhile and I am soon to release the product. The work around was to make stored procedures in the fetched object and use a
NSFetchRequest *fetch = [model fetchRequestFromTemplateWithName:@"myTemplate1" substitutionVariables:subs];
This eliminates the use of Predicate on the FetchedResultsController.
When I want to use predicate I just make sure that I am using a local managedObjectContext and pass the Array itself to work on elsewhere. NSArray *array = [moc executeFetchRequest:fetchRequest error:&error]; return array;
This is a safer bet and allows you to make many view of the same data.
Are you using more than one NSManagedObjectContext
? The post you linked to was using multiple NSManagedObjectContext
instances improperly which is the root of his problem. It is not a bug in the NSFetchedResultsController
but a misunderstanding on his part as to how it works.
With regard to your issue; first question: do you have a break in the case
before the one you showed?
What does the editing code look like? You show a predicate but not the code that is editing the object that you state is causing the NSFetchedResultsChangeDelete
to fire.
In my post I'm dealing with a known bug in NSFetchedResultsController
(see https://devforums.apple.com/message/139580#139580) which does a pointer comparison between two objects in two different managed object context, instead evaluating objectID
, so I think this is not your problem.
Is your object treated as deleted just if you modify its date
outside the interval specified in the NSPredicate
or for any other modification as well?
精彩评论