Setting .fetchBatchSize causes entire collection to be immediately traversed

Using an @FetchRequest in my SwiftUI-redesigned app, I was looking to improve performance of my search and filtering on a List that has potentially a large amount of data. One of the things I was asking about was how to load some data initially and then fetch additional objects as the user scrolls.

In a WWDC lab today, while viewing my code the Apple engineer noted I had set a .fetchLimit on my FetchRequest, and suggested that I should be setting a .fetchBatchSize. It sounded like that was designed to do exactly what I wanted.

However, having attempted this, I can see from the console output that when I set a .fetchBatchSize of 50 and go to the view, it immediately loops through the entire collection of thousands of objects, attempting to load them into memory, and as some contain images this eventually crashes with an out of memory error.

This data is presented in a List. Originally, inside that list there was a ForEach inside that list but the same problem was seen when I removed the ForEach and used:

List(entries) { entry in
    if let entryData = viewModel.entryData(for: entry) {
        TimelineEntryView(entryData: entryData)
    }
}

Can you advise on what might be going on here? I recall that in the previous iteration of my app, in UIKit and using an NSFetchedResultsController I had the exact same symptom: setting a fetch batch size immediately traversed the whole collection in the datastore, leading to terrible performance rather than the hoped-for good performance. So I did not set a batch size then either.

Am I holding this wrong? Is there something that might be triggering this?

This is a fascinating lead I have not previously found: https://stackoverflow.com/a/42751426/842106

I wonder whether my custom NSManagedObject subclasses in Swift are somehow to blame, causing unwanted bridging to Swift types, or whether I need to annotate the @FetchRequest in some way to prevent this happening...

The behavior you described doesn't sound right. Unless something goes wrong, @FetchRequest should automatically manage the batch size for you. So ... would you mind to provide a testing project that can reproduce the issue so we can take a closer look?

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Yes, I'll put together a test project and try to reproduce the issue.

Setting .fetchBatchSize causes entire collection to be immediately traversed
 
 
Q