Anurag Bhakuni
Anurag Bhakuni

Reputation: 2439

Core data multithreading issues

I have implemented core data in Multithread environment, I have some doubt and issue related to it which I am listing down below:-

  1. Several blogs and SO answers are saying you should have single NSPersistentStoreCoordinator(PSC) but as per my understanding, 'PSC' should be equal to the number of ManagedObjectModel. Please correct me if I am wrong.

  2. As per doc, the ManagedObjectContext objects should be equal to the number of threads we are creating to perform the activity in a particular model. To my surprise, I have used a single ManagedObjectContext object from different threads and performing fetching action simultaneously without any crash, please find the code below:-

    I am calling the function below from different threads and making sure only a single instance of MOC is created. Please clear all the above doubts I have

func fetchUserDetail(productId : Int) -> User_Details?  {
    
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "User_Details")
    do {
        fetchRequest.predicate = NSPredicate(format: "product_id == %d", productId)
        
        let results:[User_Details]? = try (singleinstancemanagedObjectContext.fetch(fetchRequest) as? [User_Details])
        
        if let results = results {
            ..... logic .....
        }
    } catch let error as NSError {
    }
    return nil
    
}

Upvotes: 1

Views: 56

Answers (1)

Shreeram Bhat
Shreeram Bhat

Reputation: 3157

  1. An "NSPersistentStoreCoordinator" can only handle one NSManagedObjectModel. You are right here. But having multiple "NSPersistentStoreCoordinator" requires multiple "NSManagedObjectModel"s(.xcdatamodeld files). This case is very rare.

  2. Concurrency crashes are elusive by nature. They only happen when multiple threads access the same data at the same time with nano second precision. These are hard to debug bugs that usually occur in production when 100s of users using the app. The last thing you want to say to a user is we have lost all your data(got corrupted or crashed whatever). So you are better off listening to the documentation here. We did the same mistake of passing NSManagedObjects between different threads in one of our old apps and paid the price. It took long time to refactor the code. At last from Core Data Programming Guide link.

The NSPrivateQueueConcurrencyType configuration creates its own queue upon initialization and can be used only on that queue. Because the queue is private and internal to the NSManagedObjectContext instance, it can only be accessed through the performBlock: and the performBlockAndWait: methods.

Here is another from the same page,

NSManagedObject instances are not intended to be passed between queues. Doing so can result in corruption of the data and termination of the application. When it is necessary to hand off a managed object reference from one queue to another, it must be done through NSManagedObjectID instances.

Upvotes: 1

Related Questions