my problem is very strange and I am asking for help. I want to explain to you how my system works. I have two problem with this.
I am making application which have two tables. I am using core data. Tables are Categories and Products, in core data I have established one to many relationship Category can have multiple Products, Product can hove one Categroy.
Here is basic schema
Category {
site_id
name
allProducts ->> Product
}
Product {
site_id
name
category -> Category
}
In that application I have updating process, and that process works in backgournd thread. I have created context for that thread and all changes I am storing in that context.
All caluclation I am executing in background thread in
[context performBlock:^{
// all my operations for updating storing categories and products
}]
This is flow of updateding process
From server get JSON with info which category has which products array((category_site_id > array(product_site_id1, product_site_id2...))
Pass through categories JSON and store category entity, I am getting name and site_id from JSON and create entity and set these properties
Pass through products JSON and create product entity and set name and store_id from properties from JSON
Then main part
I am going foreach category from JSON and get all products site_id as NSArray, I am using fetch request with predicate and IN criteria to get all products entities from context which have site_id IN array. But I always got zero results. That is strange because I am calling fetch results on context in background thread and I also updated that context in step 3 and 4.
Then I try next thing, before step 6 I [context save:&error]
and added sleep about 30 secconds and when after that program run into step 6 all work funtastic my fetch results get products with predicate with IN criteria. That is a my first problem if you understand me, I can not get products by IDs I need to wait about 30 sec to context store to SQLLiteDB it is very strange. Also this is strange because when I want to get category with fetch request by id I can get it without problems (maybe that it is because step 5 takes about one minute).
My next problem is when I wait that 30 sec and then passing trought categories. Based on category site_id I get Category entity from context and also in step 6 I get all products base on product site_ids geted by JSON and fetch request and now I want to add products to category and I call next
[category setAllProducts:results] // results are NSSet of product, category is entity object
NSError *error = nil; [context save:&error];
and I do that foreach categroy (geted in step 3 from server in JSON format)
when all is done I can not see products in categroies on UI I am also waiting some time to all data be stored in DB but nothing heppenes,
AND THEN WHEN I STOP APPLICATION AND RUN IT AGAIN I CAN SEE PRODUCTS IN CATEGORIES :(
very strange problem please help me I do not know where I am a wrong. I can post parts of code, code is not small and I asking for help based on description of process.
Thank you very much
To use Core Data in a multithreaded environment, ensure that: Managed object contexts are bound to the thread (queue) that they are associated with upon initialization. Managed objects retrieved from a context are bound to the same queue that the context is bound to.
functions are thread safe and can be called from other threads. A NSManagedObject cannot be shared across threads. A NSManagedObjectID can be shared across threads. Changes from one NSManagedObjectContext can be merged into another NSManagedObjectContext , even on another thread.
If you need to pass a managed object from one thread to another, you use a managed object's objectID property. The objectID property is of type NSManagedObjectID and uniquely identifies a record in the persistent store.
NSManagedObjectContext is not thread safe However, if you do so, you're going to negatively impact your user's experience. There are two methods available on the NSManagedObjectContext class to help with concurrency: perform(_:)
My understanding is that you are using child contexts. Child contexts are affected by many (many!) bugs you have to deal with.
Pretty good article about that topic here:
http://wbyoung.tumblr.com/post/27851725562/core-data-growing-pains
My advice on that matter is to use a context directly connected to the store coordinator, not a child context. Everything will work fine using such a setup. You can use a private queue context of course.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With