简体   繁体   中英

CoreData blocking when setting an attribute on a managed object, in a multithread context

I have a multi-threading problem on Core Data.

Some NSOperation update different NSManagedObject attributes in background with the following instructions:

BKArtistData *artistData = [self artistDataForName:bandName];
artistData.bandId = bandId;
[self save];

The artistDataForName performs a fetch on a context shared by all the background threads. (I also tried with a one-context-per-thread strategy, things were still blocking).

My problem is that only 1 thread can perform the updates. The other threads get stucked on the

artistData.bandId = bandId; 

line.

Eventually, I could make things work making the update to be executed from the main thread. Still, any idea where the blocking was coming from here?

The Core Data documentation states that NSManagedObjects are not thread-safe. Unless you have a separate ManagedObjectContext for each thread, you're not following the guidelines and it is highly likely that you'll have problems.

You may be able to achieve what you want by doing the update on the main thread:

dispatch_async(dispatch_get_main_queue(), ^{
    artistData.bandId = bandId;
});

However, just pushing this update to the main thread may not be enough since the NSManagedObject that you have passed to your background thread may have already been deleted or changed in another thread before you come to make this update... hence the need for separate ManagedObjectContexts and then using the Core Data tools for managing updates and dealing with conflicting changes.

Further: Just read your question more carefully. Given you're performing a fetch in artistDataForName, you definitely should be using a separate managed object context for each thread.

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