NSPredicate cause update editing to return NSFetch

2019-03-30 15:27发布

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://matteocaldari.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.

4条回答
啃猪蹄的小仙女
2楼-- · 2019-03-30 16:07

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.

查看更多
混吃等死
3楼-- · 2019-03-30 16:09

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.

查看更多
虎瘦雄心在
4楼-- · 2019-03-30 16:31

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.

查看更多
趁早两清
5楼-- · 2019-03-30 16:34

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?

查看更多
登录 后发表回答