What happens if I put Dispatch.main.async block inside Dispatch.global.async?

816 Views Asked by At

I have a case where I am saving data to Realm Database inside Dispatch.global in background thread then inside same thread I have called Dispatch.main.async to fetch data from Realm and update UITableView Data.

The problem is I am getting less number of Data (data.count). Suppose total data count is 10 then sometimes I am get all the data sometimes and sometimes less then 10.

Why does this happen?

Following is the example code snippet

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

In above code removeDataFromRealm(), saveDataToRealm(data), getDataFromRealm() are realm class static func where I save, remove, get data from realm database

I have debug the code from all the aspect that I understand and it saves (saveDataToRealm(data)) all the data and then fetch (getDataFromRealm()) the data, according to my understanding then why it sends me less number of data sometimes

There is no filter applied to RealmManager getDataFromRealm() static methods, while fetching data.

Suppose above code goes in race condition then what happens in below code snippet

    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)
            }
        }
    }

As getImageFromServer() first fetch data then Dispatch.main.async is executed after converting "Data(contentsOf: url)" to data which obviously is time taking.

Why does it work differently in above cases?

1

There are 1 best solutions below

1
On

If your RealmManager.removeDataFromRealm() and/or RealmManager.saveDataToRealm(data) is async then you have got yourself into a race condition here as there is nothing guarantees that your data is saved before the code in DispatchQueue.main is executed. What you can do is to use DispatchGroup to wait for the two methods above to finish before entering DispatchQueue.main.async.

To answer the question in the title, if you are in global queue and then execute codes in global queue, what swift does is essentially switching from the former to the later.