Reputation: 31
i am using for loop to iterate photos and adding it to core data but it blocks UI thread while in process I am using
self.fetchResult = PHAsset.fetchAssets(with: .image, options: allPhotosOptions)
DispatchQueue.main.async { }
for i in 0 ..< self.fetchResult.count {
GenericCoreData.saveEntity("Details")
}
Upvotes: 1
Views: 5817
Reputation: 19592
I had the same question. In my situation the loop was locking the main thread. It wasn't a simple count from 1 -10, on every iteration two other internal functions were running so the UI was blocked. I needed to run it in the background and then when it finished update the UI on the main thread.
I used a background task from this answer and added a loop to it
1- Create an extension
on DispatchQueue
and add this static
method to it
extension DispatchQueue {
static func myBackground(delay: Double = 0.0, background: (()->Void)? = nil, completion: (() -> Void)? = nil) {
DispatchQueue.global(qos: .background).async {
background?()
if let completion = completion {
DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: {
completion()
})
}
}
}
}
2- Call the above method and add your loop inside the first part:
DispatchQueue.myBackground(background: {
// do something in background like run a loop in the background
for num in 1..<10 {
// run function 1
// run function 2 after function 1 is finished
}
}, completion:{
// when background job finished, do something in main thread
})
Another method you can also use is a DispatchGroup
let dispatchGroup = DispatchGroup()
for num in 1..<10 {
// ** call this to enter the group **
dispatchGroup.enter()
// run function 1
// run function 2 after function 1 is finished and call **dispatchGroup.leave()** to exit the group when function 2 is finished
// make sure to call **dispatchGroup.leave()** or this will never end
}
dispatchGroup.notify(queue: .global(qos: .background)) {
DispatchQueue.main.async { [weak self] in
// when background job finished, do something in main thread
}
}
Upvotes: 1
Reputation: 3657
You can use DispatchQueue like this.
DispatchQueue.global(qos: .background).async {
for i in 0 ..< self.fetchResult.count {
GenericCoreData.saveEntity("Details")
}
}
Upvotes: 3