How does this cause deadlock (once in a while) and how do I unravel this

前端 未结 2 567
攒了一身酷
攒了一身酷 2021-01-27 14:06
@synchronized (self.class)     {
    fetchedObjects = [moc executeFetchRequest:request error:&error];
}

moc is a managedObjectContext

It ca

2条回答
  •  一整个雨季
    2021-01-27 14:37

    You shouldn't be @synchronize-ing calls to executeFetchRequest:

    The executeFetchRequest:error: method intrinsically scales its behavior appropriately for the hardware and work load. If necessary, the Core Data will create additional private threads to optimize fetching performance. You will not improve absolute fetching speed by creating background threads for the purpose. It may still be appropriate, however, to fetch in a background thread or queue to prevent your application’s user interface from blocking. This means that if a fetch is complicated or returns a large amount of data, you can return control to the user and display results as they arrive.

    Core Data Programming Guide: Concurrency

    Basically if you're returning a lot of objects and processing them, it's best to do that from a private queue context (since you can then use the returned objects on that private queue and process them off the main queue).

    If you have a main queue context, only use it from the main queue.

    Also, child contexts execute fetch requests by passing them to their parents. What happens (from what I can tell) is that the predicate gets evaluated on the persistent store (SQL), and on the unsaved objects in each MOC in the chain. This means that if you, say, override a getter that is used in a predicate, it will be called on those unsaved objects in memory (whereas the SQL predicate uses the raw DB values to compare against). You can deadlock a parent context by blocking its queue from a child context.

提交回复
热议问题