Что произойдет, если я помещу блок Dispatch.main.async внутрь Dispatch.global.async?

У меня есть случай, когда я сохраняю данные в базу данных Realm внутри Dispatch.global в фоновом потоке, а затем внутри того же потока я вызываю Dispatch.main.async для извлечения данных из Realm и обновления данных UITableView.

Проблема в том, что я получаю меньше данных (data.count). Предположим, что общее количество данных равно 10, тогда иногда я получаю все данные, а иногда и меньше 10.

Почему это происходит?

Ниже приведен пример фрагмента кода

func getData(data: [String]) {
    DispatchQueue.global(qos: .background).async {
        RealmManager.removeDataFromRealm()
        RealmManager.saveDataToRealm(data)
        Dispatch.main.async {
            let dataFromRealm = RealmManager.getDataFromRealm()
            self.sendDataToUI(dataFromRealm)
        }
    }
}

В приведенном выше коде removeDataFromRealm(), saveDataToRealm(data), getDataFromRealm() являются статическими функциями класса области, в которых я сохраняю, удаляю, получаю данные из базы данных области

Я отлаживаю код со всех аспектов, которые я понимаю, и он сохраняет (saveDataToRealm(data)) все данные, а затем извлекает (getDataFromRealm()) данные, согласно моему пониманию, тогда почему он иногда отправляет мне меньше данных

К статическим методам RealmManager getDataFromRealm() фильтр при выборке данных не применяется.

Предположим, что приведенный выше код переходит в состояние гонки, тогда что происходит в приведенном ниже фрагменте кода.

    func getImageFromServer (url: URL) {
        DispatchQueue.global(qos: .background).async {
            do {
                let data = try Data(contentsOf: url)
                DispatchQueue.main.async {
                    self.imageView.image = UIImage(data: data)
                }
            }catch {
                print(error)
            }
        }
    }

Поскольку getImageFromServer() сначала извлекает данные, затем выполняется Dispatch.main.async после преобразования «Data (contentsOf: url)» в данные, что, очевидно, требует времени.

Почему это работает по-разному в вышеуказанных случаях?


person Manish Patel    schedule 16.11.2018    source источник
comment
Ваши вызовы области, вероятно, занимают много времени, что означает, что ваша выборка инициируется до завершения сохранения.   -  person Rakesha Shastri    schedule 16.11.2018
comment
Являются ли реализации RealmManager.removeDataFromRealm и RealmManager.saveDataToRealm асинхронными или синхронными?   -  person rmaddy    schedule 16.11.2018
comment
@RakeshShastri Я отладил код, и в соответствии с точками останова отладки он удаляет данные, затем сохраняет данные, а затем извлекает данные ..   -  person Manish Patel    schedule 17.11.2018
comment
@rmaddy Насколько я понимаю, библиотека Realm работает асинхронно. Моя реализация метода синхронна   -  person Manish Patel    schedule 17.11.2018
comment
RealmManager.saveDataToRealm (данные) - это асинхронная функция? я имею в виду, что внутри saveDataToRealm какая-либо операция выполняется асинхронно?   -  person Mihir Mehta    schedule 19.11.2018
comment
Блок Dispatch.main.async внутри асинхронного блока используется для выполнения операций в основном потоке. поэтому в соответствии с этим вы извлекаете данные асинхронно, а затем, когда вы хотите отображать данные в пользовательском интерфейсе, используйте основной поток. Если вы все еще сталкиваетесь с проблемой, должна быть проблема с вашим запросом на выборку. В запросе должен быть какой-то предел, проверьте его по глубине.   -  person Anas Sabir    schedule 19.11.2018
comment
@mihirmehta Внутри RealmManager.saveDataToRealm(data) нет асинхронных операций, но у меня есть сомнения относительно библиотеки метода записи Realm.   -  person Manish Patel    schedule 19.11.2018
comment
@AnasSabir я не думаю, что есть какие-либо проблемы с ограничением запросов, потому что некоторое время я получаю все данные. А что касается асинхронного кода, то весь мой код внутри функции области синхронизирован, но у меня есть сомнения относительно методов области, независимо от того, синхронизированы они или асинхронны   -  person Manish Patel    schedule 19.11.2018


Ответы (1)


Если ваши RealmManager.removeDataFromRealm() и/или RealmManager.saveDataToRealm(data) являются асинхронными, то вы попали в состояние гонки, поскольку ничто не гарантирует, что ваши данные будут сохранены до того, как код в DispatchQueue.main будет выполнен. Что вы можете сделать, так это использовать DispatchGroup, чтобы дождаться завершения двух методов, описанных выше, прежде чем вводить DispatchQueue.main.async.

Чтобы ответить на вопрос в заголовке, если вы находитесь в глобальной очереди, а затем выполняете коды в глобальной очереди, что Swift делает, по сути, переключается с первого на более поздний.

person Linh Ta    schedule 19.11.2018
comment
Пожалуйста, проверьте мой отредактированный вопрос, я ценю ваш ответ. Спасибо. - person Manish Patel; 19.11.2018