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?
If your
RealmManager.removeDataFromRealm()
and/orRealmManager.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 inDispatchQueue.main
is executed. What you can do is to useDispatchGroup
to wait for the two methods above to finish before enteringDispatchQueue.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.