问题
I am using GCD to start a long-running background process ('run_loop') that creates an NSManagedObjectContext ('MOC'), monitors CoreData objects, and sometimes (when they're ready) uploads a serialization of them to a webserver and then deletes them.
I am using AFNetworking for the HTTP calls. The problem is in the request completion handler blocks, as the blocks run in a different thread to the owner of the MOC, which isn't supported by CoreData.
I have tried storing the NSThread from the start of the GCD run_loop block, and using performSelector:onThread:run_thread but this just doesn't seem to actually call the selector at all.
I have tried using dispatch_sync(run_queue) but this doesn't guarantee the thread is the same, only the GCD queue. A different MOC save in the main thread later hangs.
Eventually the only thing that worked was to set a boolean in the completion callback handler, and to introduce extra logic to detect the boolean switch and to perform the MOC work from the main run_loop.
Would anyone be able to suggest a more elegant fix? Or is CoreData simply not compatible with an AFNetworking request started from a GCD queue, and I should look at a lower-level thread control from the start?
回答1:
Hmm .. the recommended way to deal with MOC and threads is to always make a new MOC that is a sub-moc of your main thread's MOC. Let the main thread do all the saving, but your GCD threads can basically merge changes to the main MOC.
I've had pretty good success working with https://github.com/magicalpanda/MagicalRecord/ to facilitate this in a simpler fashion.
来源:https://stackoverflow.com/questions/11428324/coredata-not-compatible-with-an-afnetworking-request-from-a-gcd-queue