My project uses the RunLoop method.
RunLoop.current.run(until: Date.init(timeIntervalSinceNow: 1.0))
[iOS14.8 Device:iPhone7 - iPhone12]
It works well. GUI is not blocked.
[iOS15.1 Device:iPhoneXS - iPhone13]
It works as same as sleep(1) That means GUI is blocked for 1.0 seconds.
[iOS15.1 Device:iPhone8] It works well. GUI is not blocked.
I am very confused this issue. Is it a well known issue? Regards.
I got the information from Apple by DTS.
The comments are below.
This is a known issue. However, nested run loops are not a recommended practice today due to complexities of timing event loops and the response chain. Could you replace the logic which requires spinning the run loop with a call to performSelector or a timer instead?
So I rewrote the code using "An escaping closure to handle the completion callback with Timer". It works good, but there was a lot of code changes and the nesting was very deep(In the sense of the caller). I had no other ideas.
ex)
func delayedDisplay(completion: @escaping () -> Void) {
let partString = moji.prefix(1)
if (moji == "") {
print("<END>")
// 5. Invokes the completion handler when the recursive work ends.
completion()
return
}
print(partString, terminator: "")
// 2. Schedules a single use timer to perform recursion.
_ = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { timer in
// 3. Perform some work.
if let range = self.moji.range(of: partString) {
self.moji.replaceSubrange(range, with: "")
// 4. Passes the completion handler again for proper recursion.
self.delayedDisplay(completion: completion)
}
}
}