使用SwiftUI Menu时控制台出现禁用递归触发日志报错如何解决
问题原因及解决方案
告警触发原因
- 第一条
UILog类告警属于iOS 15 ~ iOS 16.3 版本中SwiftUI Menu的系统实现缺陷,属于系统误报的日志,和业务代码逻辑无关,只要在Menu内部使用动态生成的ForEach列表就大概率触发该日志输出,完全不影响功能正常运行,苹果已经在iOS 16.4及以上系统版本修复了该日志误报问题。 - 第二条
UICollectionViewRecursion类告警由代码实现问题触发:- 当前
months是计算属性,每次视图刷新都会重新执行日历查询逻辑,导致Menu内容反复重绘 - ForEach循环内每次迭代都会创建新的
DateFormatter实例,极高的渲染成本触发了不必要的视图重绘,进而触发集合视图递归日志告警。
- 当前
优化方案
- 提前缓存静态资源,避免重复计算和创建实例,参考修改后的代码:
// 全局缓存月份格式化器,避免重复创建 private let monthFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateFormat = "MMMM" return formatter }() // 用状态变量缓存月份列表,避免每次渲染都重新计算 @State private var months: [Date] = [] var body: some View { Menu("Options") { ForEach(months, id:\.self) { month in Button(monthFormatter.string(from: month)) { selectedDate = month } } } .onAppear { // 仅在视图首次出现时计算一次月份列表,必要时可在年份变化时更新 months = calendar.createDate( interval: calendar.dateInterval(of: .year, for: Date()), matching: DateComponents(day: 1, hour: 0, minute: 0, second: 0) ) } }
- 如果应用仅需要兼容iOS 16.4及以上版本,优化后两类告警都会自动消失;如果需要兼容更低的iOS版本,忽略
UILog类告警即可,不会对线上用户产生任何影响。
内容的提问来源于stack exchange,提问作者kAiN
相关产品推荐
相关产品推荐

