I couldn't find any direct answer online nor within the docs about this.
If I'm setting up CADisplayLink with the following:
let displayLink = CADisplayLink(target: self, selector: #selector(updateShimmer))
displayLink.add(to: .current, forMode: .common)
@objc func updateShimmer() {
print(Thread.isMainThread)
}
I'm getting true. I know that I can wrap this within a DispatchQueue.main but I was wondering, is it always dispatched on the main queue? Or should I wrap it anyway?
You do not need to manually dispatch code inside your display link handler to the main thread. Timers and display links added to a particular run loop will always run on the thread associated with that run loop. For more information, see Threading Programming Guide: Run Loops.
Bottom line, if you
add(to:forMode:)to the main run loop, the main run loop always runs on the main thread.That having been said, if you want to make sure it always runs on the main thread, I would suggest being explicit and adding it to
.main, not just.current. That removes any ambiguity:Note, I also tweaked the signature of
updateShimmerto accept a parameter. The display link will be passed to it. It’s often useful to have that reference inside the method. And, regardless, it makes one's code more self-evident: You can just glance at this method now and understand that this is a display link handler: