This is your stated goal: βI need Person objects that need to be grouped by section using a group of relationship objects, a name attribute, and NSFetchResultsController to select in small batches as they scroll, rather than up as they are now.β
The answer is a bit complicated, primarily because of how NSFetchedResultsController sections NSFetchedResultsController built, and how this affects the behavior of the selection.
TL DR; To change this behavior, you will need to change the way NSFetchedResultsController partitions are created.
What's happening?
When an NSFetchedResultsController given a NSFetchedResultsController query (fetchLimit and / or fetchBatchSize), several things happen.
If sectionNameKeyPath not specified, it does exactly what you expect. The fetch function returns an array of proxy results with "real" objects for the first fetchBathSize element. For example, if you have setFetchBatchSize up to 2, and your predicate corresponds to 10 items in the repository, the results contain the first two objects. Other objects will be retrieved separately as they become available. This provides a smooth playback of paginated answers.
However, when the sectionNameKeyPath parameter is sectionNameKeyPath , the resulting result controller should do a little more. To compute sections, he needs to access this key path for all objects in the results. He lists 10 points in the results in our example. The first two have already been received. The remaining 8 will be selected during the listing to get the key value needed to create the section information. If you have many results for your sample query, this can be very inefficient. There are a number of public errors regarding this feature:
NSFetchedResultsController initially takes too long to configure partitions
NSFetchedResultsController ignores the fetchLimit property
NSFetchedResultsController, table index and buyback performance
... and a few more. When you think about it, it makes sense. Creating NSFetchedResultsSectionInfo objects requires that the recipient of the results display each value in the results for sectionNameKeyPath , combine them with a unique combination of values ββand use this information to create the correct number of NSFetchedResultsSectionInfo objects, set the name and title of the index, know how many objects the section contains in the results, etc. .d. There is no such way to handle the general use case. With that in mind, your tool tracks may make more sense.
How can you change that?
You can create your own NSFetchedResultsController , which provides an alternative strategy for creating NSFetchedResultsSectionInf o objects, but you may run into some of the same problems. For example, if you use the existing fetchedObjects functions to access the elements of the selection results, you will encounter the same behavior when accessing objects that are errors. For your implementation, you will need a strategy to solve this problem (it is possible, but it depends on your needs and requirements).
Oh god no. What about a temporary hack that just makes it work a little better, but doesn't fix the problem?
Changing the data model will not change the behavior described above, but may slightly affect performance. Batch updates will not have a significant impact on this behavior, and in fact will not play well with the selected result controller. However, it might be much more useful for you to set relationshipKeyPathsForPrefetching instead to include your "group" relationships, which can greatly improve crash behavior and behavior. Another strategy may be to perform a different sample to batch crash these objects before trying to use the selected result controller, which will more efficiently populate the various levels of Core Data data caches in memory.
The NSFetchedResultsController cache is primarily for section information. This prevents the need for a full recount of sections at each change (at best), but it can actually make the initial sample for assembly of sections occupied much longer. You will need to experiment to make sure the cache is worth your use.
If your main problem is that these operations with the main data block user interaction , you can unload them from the main stream. NSFetchedResultsController can be used in the context of a private queue (background) , which will prevent the locking of user interfaces of Core Data operations.