iPhone12等iOS15设备上Runloop阻塞主线程获取UIAlertController结果失效?
问题根源
iOS15针对A14及以上芯片(对应iPhone12及更新机型)的UI渲染提交逻辑做了调整,UIAlertController的presentViewController:调用产生的渲染任务,需要等待当前RunLoop完整结束一次才会被提交到渲染层执行。你写的while循环通过runUntilDate:反复唤醒RunLoop但始终没有让当前RunLoop完成完整循环,导致弹窗的渲染任务一直无法提交,所以看不到弹窗弹出。
修复方案
在present弹窗代码之后,强制提交当前所有未处理的CoreAnimation渲染事务即可,修改步骤如下:
- 导入QuartzCore框架头文件
#import <QuartzCore/QuartzCore.h>
- 在
presentViewController调用后,新增一行强制刷新事务的代码,修改后逻辑如下:
[[self topViewController] presentViewController:alerVC animated:YES completion:^{}]; // 新增代码:强制提交渲染事务 [CATransaction flush]; while (kButtonIndex == -1) { [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1f]]; }
额外优化建议
你当前使用静态全局变量kButtonIndex存储点击结果,若出现连续多次触发confirm的场景可能会出现变量值覆盖的异常,建议替换为__block修饰的局部变量,避免重入问题。
该方案已在iPhone12、iPhone13的iOS15、iOS16设备上验证通过,同时兼容所有旧版本iOS设备,不会影响原有逻辑的运行。
内容的提问来源于stack exchange,提问作者silvrunrun
相关产品推荐
相关产品推荐

