NSFetchedResultsController crashing on performFetch: when using a cache

后端 未结 12 2172
迷失自我
迷失自我 2020-12-23 14:05

I make use of NSFetchedResultsController to display a bunch of objects, which are sectioned using dates. On a fresh install, it all works perfectly and the objects are displ

12条回答
  •  悲哀的现实
    2020-12-23 14:13

    I found via the Ray Wenderlich forums that

    Note that it only crashes when the fetch request is not created yet when you add something new to the datastore, i.e. when the Locations view isn't loaded yet. If the view is loaded already, then it works fine. Odd, eh?

    So, what happened in my case was this:

    1. The normal launch process entails constructing an NSFetchedResultsController.
    2. Because there are thousands of objects being fetched, a fresh fetch takes considerable time. To mitigate this, the fetch a) uses a cache, and b) happens in the background, allowing other activities to continue
    3. Normally, though the UI is responsive and the user can do stuff, the fetch is complete long before the user might express a desire to create a new object.
    4. However, sometimes the app will be launched in the background - say, from a WatchKit event, or a background fetch, etc) - and part of the launch will entail creating a new object in the datastore immediately.
    5. If the new object was created before the fetch was complete, the app would crash.

    The solution is to ensure that The fetch is complete before creating an object (which would affect the fetch).

    Alternatively you could delete the cache, but that is less performant practically speaking.

    Note that the admonition from the debugger that

    You have illegally mutated the NSFetchedResultsController's fetch request, its predicate, or its sort descriptor without either disabling caching or using +deleteCacheWithName:

    simply does not capture this situation whatsoever, in that what you have changed was not the request, predicate, or sort descriptor, but rather more accurately could be described as having mutated the result set while the fetch was in progress.

    It took me forever to track down this tiny piece of trivia. I hope you benefit.

提交回复
热议问题