简体   繁体   中英

Using NSPrivateQueueConcurrencyType child context with NSPrivateQueueConcurrencyType parent context

I'm having trouble using a child context as a scratch pad with NSPrivateQueueConcurrencyType.

My core data stack looks like this: 核心数据堆栈

The view controllers use the Main Context. The Worker Context is used for importing data from an API. I'm using mergeChangesFromContextDidSaveNotification to merge changes between the Main and Worker contexts. If I leave the Worker Child context out of the equation, things seem to be working correctly.

However, I'd like to use the worker child context as a scratch pad while importing objects. Some of the data requires building nested objects, and if there is an error somewhere in the building process, I'd like to just throw that context away. If the build succeeds, I'd expect to be able to save the worker child context, have it push the changes into the worker context, which can then save and merge the changes to the main context.

However, when I try to execute a fetch request in the Worker Child Context to do a find or create, even though it is done inside a performBlock on the Worker Child Context, I'm getting a multi-threading assertion.

I'm not sure what code snippets would be helpful in answering this question, but my main concern is that my overall approach isn't going to work. Is having a private queue context as the child of another context a bad idea?

EDIT:

The crash I'm experiencing is when a worker child context tries to execute a fetch request to do a find or create operation. It isn't using any managed objects in the predicate, and its wrapped in a performBlockAndWait . The explanation I'm getting is 'NSInternalInconsistencyException', reason: 'statement is still active' The crash is intermittent, but so far it appears that it only happens when I have nested worker child contexts. (ie the worker child context in my diagram would have a child context of its own creating objects)

The fetch request causing the crash is always for a find or create operation, so its attempting to fetch any objects with a unique identifier property matching the identifier of the objects being imported. So the predicate is always something like "identifier in ["1234", "abc", "etc" ]

As I mentioned in a comment, I was originally using a PSC -> Private Context -> Main Context -> Private Worker Context setup. I'm experience UI freezing while the worker context fetches and saves while importing data, so I'm trying to refactor to this stack in order to free up the UI.

Showing your fetch and its predicate will help to determine what is going on. It sounds like you are accessing a NSManagedObject across thread boundaries, perhaps using one in your predicate?

BTW, if you move your workers under your main queue you won't need to deal with consuming notifications. Everything else would be exactly the same but you would have less code to deal with and less risk of a threading issue.

I initially had the workers under my main queue. PSC -> Private Queue -> Main Queue -> Private Workers. I'm refactoring to the setup I'm asking about because I'm experience the UI being blocked while the worker contexts are fetching / saving for find or create imports. Is there another way to optimize performance that you would recommend other than refactoring the core data stack?

Have you run instruments to make certain that the block is from the child MOC? In every case I have heard of that issue I have found it to be something else (usually UI related) that was the actual source of the issue. Unless you are fetching THOUSANDS of objects against a bad predicate you should not feel a hit for a fetch. Even then the predicate an be optimized to solve the issue.

As for a save, you can either A) increase your save frequency or B) set up a private MOC to be the writer to disk. I prefer B so that all saves are guaranteed to be asynchronous.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM