> On 31 Jan 2015, at 01:20, Steve Mills <sjmi...@mac.com> wrote:
> 
> I'm trying to learn Core Data. I have a working document model hooked up to a 
> table view (OS X). I have an import method that uses FSDirectoryEnumerator to 
> add an object for each file in the folder. Oky doke! But that blocks for a 
> few seconds while it loops. So I'm trying to make it threaded. One example I 
> saw uses GCD. It kinda seemed to work when I had a bunch of printfs in there 
> so I could watch it progress, but when I took them out it just crashed at 
> some point, and it still blocked any sort of user events.
> 
> Next I tried sticking the entire import operation into a block via 
> NSOperationQueue's addOperationWithBlock:. That throws because some set was 
> being changed by multiple threads. Then I tried the suggestion of using a 
> private NSManagedObjectContext in the block. That got me somewhere, but of 
> course the data didn't populate my table. I tried the 
> NSManagedObjectContextDidSaveNotification trick, but I couldn't get that to 
> work.
> 
> Reading the Concurrency with Core Data page online says the information is 
> outdated. Where do I find current documentation? Or better yet, an actual 
> example that actually works? My brain is about to explode, and nobody wants 
> to clean that up.
> 

Oh yes the documentation does say that doesn't it - that's a shame. My first 
recommendation right off the bat (and it's the same one I make often) is to go 
watch the core data videos from WWDC going back to about 2011 when I believe 
all the 'new' concurrency was introduced. It's a time-investment but there's 
loads of good stuff in there which I find helps immensely and you really can't 
find out any other way. (The 2014 video has a brief runthrough towards the 
start of the history of concurrency with Core Data, that's at least a start). 

At this point, NSThreadConfinementCurrencyType, the default since confinement 
types were introduced, is basically obsolete and there was a warning in the 
2014 WWDC video that it's going to go away. The concept of worrying about 
threads has really gone away with it. So you don't need your own operations 
queues, you should use an MOC which is NSPrivateQueueConcurrencyType and .. 
this is important .. send all requests to it on with performBlock: or 
performBlockAndWait: method. This will happily use GCD under the hood and 
serialize on the queue. Your UI should use an NSMainQueueConcurrencyType 
usually, because then you're always on the right queue when updating your UI. 

Two ways to get the results back into the MOC which is backing your table, one 
which you probably currently created as a default MOC with 
NSConfinementCurrencyType (the default) but which you should possibly think 
about changing to the main queue type. Then you have a couple of options, you 
can have an entirely separate MOC in which you do your import, or you can make 
a child MOC of the main one, of type NSPrivateQueueConcurrencyType, and do the 
import then, then 'save' it which will push the changes into the parent. I've 
done both, I prefer the separate MOC approach for bulk data import and use the 
child context paradigm mostly for discardable edits, for which it's really 
well-suited. 

NSManagedObjectContextDidSaveNotification is regrettably not a trick, it's how 
different MOCs talk to each other. So you need to get that to work. I think 
when I started with Core Data I tried hard to avoid it because I don't 'do' 
notifications, and then I gave up trying to avoid it, figured it out once and 
used it. What about it couldn't you get to work? When a context saves it sends 
that notification (plus another one before and one after to tell you things 
have changed and that it was saved) to anyone who cares to listen, it's that 
simple (as long as you called save). Core Data itself is very good at updating 
your local MOC with the results of such a notification, you really just need to 
get the notification and hand it to your MOC to figure out. If you want to be 
clever about it and inspect the notification to figure out exactly what objects 
changed and how to update your UI minimally, you can do that, a first dumb 
approach is get notification, call core data method to update local MOC, call 
reloadData on your table. Not pretty but a place to start. 

So I'd say probably go back to the notification and figure out what it was you 
were having problems with there, if you want a background import, you're going 
to need to get to the bottom of that. 


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to