From background thread, when UI needs to be updated, it needs to post to DispatchQueue.main using the async(execute:) function, as shown below:
static func executeInUIThread(_ uiThreadFunc: @escaping (Any?) -> Void, _ parms: Any?) {
DispatchQueue.main.async {
// Update UI
uiThreadFunc(parms)
}
}
It is possible to access uiThreadFunc
and parms
inside the closure because closures capture variables from their ‘surrounding context’.
But let’s say, I don’t like the lambda-style (called closures in swift) of programming. How can I do this without closures?
I attempted the following:
static func executeInUIThread(_ uiThreadFunc: @escaping (Any?) -> Void, _ parms: Any?) {
let workItem = DispatchWorkItem(block: EventLoopMgr.InternalExecuteInUIThread)
DispatchQueue.main.async(execute: workItem)
}
private static func InternalExecuteInUIThread() {
// How to execute the uiThreadfunc? This block doesn't take any parameters.
}
It doesn’t work because, the block when initialising the DispatchWorkItem takes no parameters. Therefore, I can’t pass uiThreadFunc
and parms
to this block.
I can store the uiThreadFunc
and parms
as static variables, but then it needs to be made multi-thread friendly.
Any easier way to execute in UIThread using DispatchQueue.main but without using closures?
2
Answers
Will this be helpful for you?
test
to trigger it andupdateView
is one example of youruiThreadFunc
For more Info, please
have a check GCD vs performSelector
Okay, so you can make this not anonymous:
Here I gave the name
helper
to the block of code that will be run on the main queue.Technically, a local function still counts as a closure according to the Swift Guide, but if all you want to avoid is an "anonymous" block of code, using a local function definitely achieves that.
If the local function is too much noise, you can move it out of
executeInUIThread
like this:Then you can just do:
which arguably is more readable. You