NSManagedObjectContext и любые связанные с ним управляемые объекты должны быть прикреплены к одному субъекту (поток, сериализованная очередь, NSOperationQueue с максимальным параллелизмом = 1).
Этот шаблон называется ограничением потока или изоляцией.Не существует хорошей фразы для (thread || serialized queue || NSOperationQueue с max concurrency = 1), поэтому в документации говорится: «Мы просто будем использовать« thread »для оставшейся части документа Core Data, когда мы имеем в видулюбой из этих трех способов получения сериализованного потока управления "
Если вы создаете MOC в одном потоке, а затем используете его в другом, вы нарушили ограничение потока, выставив ссылку на объект MOC двум потокам.Просто.Не делай этого.Не пересекайте потоки.
Мы явно вызываем NSOperation, потому что в отличие от потоков и GCD, у него есть странная проблема, когда -init запускается в потоке, создавая NSOperation, но -main запускается в потоке, выполняющем NSOperation.Это имеет смысл, если вы щурились на это правильно, но это не интуитивно понятно.Если вы создадите свой MOC в - [NSOperation init], то NSOperation будет услужливо нарушать ограничение потока до того, как ваш метод -main даже запустится, и вы заскочили.
Мы активно поощряем / осуждаем использование MOC и потоков любыми другими способами.Хотя теоретически возможно делать то, что упоминает Бом, никто никогда не понимал этого правильно.Все споткнулись, забыли необходимый вызов, чтобы -lock в 1 месте, «init run куда?», Или иначе превзошли сами себя.С пулами автоматического освобождения и циклом событий приложения, а также диспетчером отмены, привязками какао и KVO у одного потока есть очень много способов удержать ссылку на MOC после того, как вы попытались передать ее в другое место.Это гораздо сложнее, чем могут себе представить даже продвинутые разработчики Cocoa, пока они не начнут отлаживать.Так что это не очень полезный API.
Документация изменена, чтобы прояснить и подчеркнуть шаблон ограничения потока как единственный разумный путь.Вам следует подумать о том, чтобы попытаться сделать что-то более необычное, используя -lock и -unlock в NSManagedObjectContext, чтобы (a) было невозможно и (b) де-факто устарело.Это буквально не считается устаревшим, потому что код работает так же, как и раньше.Но ваш код, использующий его, неверен.
Некоторые люди создали MOC в одном потоке и передали их другому без вызова -lock.Это никогда не было законно.Поток, создавший MOC, всегда был владельцем MOC по умолчанию.Это стало более частой проблемой для MOC, созданных в главном потоке.MOC основного потока взаимодействуют с основным циклом событий приложения для отмены, управления памятью и некоторых других причин.В 10.6 и iOS 3 MOC более активно используют принадлежность к основному потоку.
Хотя очереди не привязаны к конкретным потокам, если вы создаете MOC в контексте очереди, правильные вещи будут происходить,Вы обязаны следовать общедоступному API.
Если очередь сериализована, вы можете совместно использовать MOC с последующими блоками, которые выполняются в этой очереди.
Поэтому не предоставляйте NSManagedObjectContext * более чем одному потоку (субъекту и т. Д.) Влюбое обстоятельство.Есть одна двусмысленность.Вы можете передать NSNotification * из уведомления didSave в MOC другого потока -mergeChangesFromContextDidSaveNotification: метод.