Re: Core data fetch and multithreading
Re: Core data fetch and multithreading
- Subject: Re: Core data fetch and multithreading
- From: Quincey Morris <email@hidden>
- Date: Mon, 22 Nov 2010 00:16:17 -0800
On Nov 21, 2010, at 23:14, vincent habchi wrote:
> I intended to lock, fetch the entity, read the corresponding attribute, and unlock. That's all I've to do. On the main thread, I lock when I mutate the set, then unlock. That's all in one place, so it's not so difficult to figure out.
*That's* not difficult to figure out, but that doesn't make it correct or complete. What if Core Data implementation within the lock-protected code does a performSelector:...afterDelay:... to make something happen later?
> The problem is that I need some kind of real time behavior. Having two MOC implies saving each time there is a mutation. And since the mutating code is tied to NSColorPanel in continuous mode, there can be many mutations as long as the user moves the color cursor until he has found the correct hue. The cycle goes like this:
>
> User picks color -> modify the set (on the main thread) -> redraw CALayer in a GCD queue -> read the set (in the GCD queue) -> displays.
>
> On the other hand, I could create a private pool of color outside Core Data and somehow insert it only when the user acknowledges its choice. That would mean copy the Core Data set, and then later replace it by the modified version. But since this set can hold several thousand elements, this looks an unnecessary waste of memory to me. Or I could have a separate memory-only persistent store with its own MOCs. But, once again, it seems unreasonably complex for the goal.
On Nov 21, 2010, at 22:26, vincent habchi wrote:
> At that point, there are, I think, two possibilities:
>
> 1. Use a single MOC and its provided mutex for accessing shared ressources (but this is strongly discouraged);
>
> 2. Create a private pool of memory in which you duplicate new objects until they are saved.
[I'm quoting you from the other thread.]
I think maybe you have more design options here. For example, you can [in principle, I think] multithread with a single MOC without locks if you pass "ownership" of the MOC around between threads that make changes, so that ownership serializes access. That requires the ownership passing to be thread safe, and you already have [I think] the perfect mechanism for that: GCD. You'd probably also want to break down your background operations so that enumeration of the relationship doesn't take place within a single GCD block execution, but where each block execution is one iteration of the enumeration. (Isn't that more GCD-like anyway?)
If you follow an approach like that, you can create a second MOC for read-only access, for purposes such as concurrent updating of the UI, without any need to merge contexts -- you can just throw away the read-only context when it's out of date. Actually, you can have as many read-only contexts as you need. The primary MOC accumulates all the changes no matter how produced, and that's the one that's saved when the document is saved.
Of course, the specific nature of your application might make such an approach infeasible, but I'm just throwing out an example of what I referred to earlier as additional design work. The problem with straight-ahead locking is that it often tends to be micro-synchronization (same as atomicity), which can fail at the macro level. Far better to analyze the problem and devise a solution via a global strategy.
Finally, when struggling with Core Data like this, it's worthwhile to repeatedly ask yourself if Core Data is the correct technology to use. Just because a solution to your application's problem can be describe in functional Core Data terms, that doesn't necessarily mean that Core Data is the best (or even a good) actual solution.
FWIW, which may not be much.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden