Сбой приложения при получении NSObjects из фона - PullRequest
0 голосов
/ 06 октября 2018

У меня есть уведомление с NotificationCenter.default, которое запускает метод удаления, который вылетает при попытке извлечь из моего магазина.Это метод:

@objc fileprivate func pruneBooks() {
    DispatchQueue.global(qos: .background).async {

        let context = cdStack.getManagedObjectContext()
        context.perform {
            do{
                let request = NSFetchRequest<Book>(entityName: "Book")
                let result = try context.fetch(request)\\ <----- CRASHES HERE
                //DO STUFF
            }catch{
                // Handle Error
            }
        }
    }
}

Вот как выглядит мой getManagedObjectContext метод:

func getManagedObjectContext() -> NSManagedObjectContext {


    let thread = Thread.current

    if thread.isMainThread {
        return mainMOC
    }

    let childContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
    childContext.parent = mainMOC

    NotificationCenter.default.addObserver(self,
                                           selector: #selector(didReceiveChildContextDidSave(notification:)),
                                           name: .NSManagedObjectContextDidSave,
                                           object: childContext)

    return childContext
}

Я не нашел способа дублировать этот сбой, я просто получаю егов отчетах о сбоях Apple.Вот обратный след:

enter image description here

Книга вызывающе и единообразно и называется Книгой, поэтому я знаю, что это не проблема.Кроме того, меня смущает вопрос, почему он не собирается работать, а не падает.

Примечание: приложение для iOS 9 и выше, поэтому я не использую NSPersistentContainer.

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

Ручное изучение потока, подобного этому, чтобы решить, какой контекст возвращать, не является хорошей идеей.

Вызывающий должен уже знать, какой контекст ему нужен, поэтому просто спросите его.Скопируйте подход PersistentContainer и используйте методы viewContext и newBackgroundContext, которые возвращают именно это.

Ваш путь миграции также будет проще, когда вы в конечном итоге отключите iOS 9.

-

Также нет необходимости вручную отправлять в фоновый поток, частный контекст уже имеет свою очередь, в которой он будет выполнять блоки .perform {}.

0 голосов
/ 06 октября 2018

Посмотрите на эту страницу документации Apple.Проблема, с которой вы сталкиваетесь, связана с тем, что вы сами создаете фоновую очередь, а у ManagedObjectContext есть своя.Доступ к этой очереди можно получить с помощью метода perform, который выполняет ваш блок в этой очереди (так в фоновом режиме).Если я прав, вы должны удалить первую строку вашей функции pruneBooks, чтобы она выглядела следующим образом:

@objc fileprivate func pruneBooks() {
    let context = cdStack.getManagedObjectContext()
    context.perform {
        do{
            let request = NSFetchRequest<Book>(entityName: "Book")
            let result = try context.fetch(request)\\ <----- CRASHES HERE
            //DO STUFF
        }catch{
            // Handle Error
        }
    }
}
...