How to switch UITableView's NSFetchedResultsController (or its predicate) programmatically?

前端 未结 4 875
故里飘歌
故里飘歌 2020-12-08 17:43

I have a UITableView that displays a subset of a large number of entities named \"Documents\". The subset is defined by another entity \"Selection\". Selections are named, o

相关标签:
4条回答
  • 2020-12-08 18:26

    Since NSFetchedResultsController(FRC) is an object, you can store instances of it like any other object.

    One useful technique is to initialize and store several FRC in a dictionary and then set the tableview controller's fetchedResultController attribute to the FRC you need at the moment. This is useful for situations such as having a segmented control to sort on different attributes or entities in the same table. This technique has the advantage of maintaining the individual FRC caches which can speed fetches up significantly.

    Just make sure to send the tableview itself a beginUpdates before you swap controllers and then an endUpdates when you are done. This prevents the table from asking for data in the narrow window when the FRC are being swapped out. Then call reloadData.

    0 讨论(0)
  • 2020-12-08 18:31

    While this may work there's a note in the iOS Reference Library that troubles me:

    Important: You must not modify the fetch request. For example, you must not change its predicate or the sort orderings.

    Source: NSFetchedResultsController Class Reference

    This additional note doesn't exist in the iOS 3.2 Reference Library.

    Just wanted to point this out.

    0 讨论(0)
  • 2020-12-08 18:41

    After I posted my question, I tried a variant of the code the OP of the other question showed. It works for me. Here it is:

    - (void) displaySelection:(Selection *)aSet
    {
        if (aSet != self.currentSelection) {
            self.currentSelection = aSet;
    
            NSFetchRequest *fetchRequest = [[self fetchedResultsController] fetchRequest];
            NSPredicate *predicate = nil;
            NSEntityDescription *entity = nil;
            entity = [NSEntityDescription entityForName:@"DocInSelection" inManagedObjectContext:managedObjectContext];
            predicate = [NSPredicate predicateWithFormat:@"selection.identifier like %@", currentSelection.identifier];
            [fetchRequest setEntity:entity];
            [fetchRequest setPredicate:predicate];
    
            [NSFetchedResultsController deleteCacheWithName:@"Root"];
    
            NSError *error = nil;
            if (![[self fetchedResultsController] performFetch:&error]) {
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
                abort();
            }       
        }
        [self.tableView reloadData];
    }
    
    0 讨论(0)
  • 2020-12-08 18:47

    An important note: if you "overwrite" a fetchController object make sure you clear its .delegate first - otherwise you'll get crashes when deleting rows, etc as the old fetchController and its delegate get events.

    0 讨论(0)
提交回复
热议问题