SwiftUI 计算属性显示“在视图更新期间修改状态,这将导致未定义的行为。”错误

Posted

技术标签:

【中文标题】SwiftUI 计算属性显示“在视图更新期间修改状态,这将导致未定义的行为。”错误【英文标题】:SwiftUI Computed Property shows "Modifying state during view update, this will cause undefined behavior." error 【发布时间】:2021-12-18 07:14:58 【问题描述】:

我已经计算出属性timeShown

我收到警告“在视图更新期间修改状态,这将导致未定义的行为。”

  if manager.selectedDateByIndex != 0 
      startIndex = 6
      endIndex = 30
   else 
      startIndex = hour
      endIndex = 24
  

这里有完整的代码

var timeIndex: Int
let currentDate = Date()
let calendar = Calendar.current
@Binding var startIndex: Int
@Binding var endIndex: Int
@EnvironmentObject var manager: BookingManager

var timeShown: String 
        let hourComponent = calendar.dateComponents([.hour], from: currentDate)
        let hour = hourComponent.hour!
        
        if manager.selectedDateByIndex != 0 
            startIndex = 6
            endIndex = 30
         else 
            startIndex = hour
            endIndex = 24
        
        
        if timeIndex < 10 
            return "0\(timeIndex):00"
         else if timeIndex > 23 
            return "0\(timeIndex % 6):00"
        
        else 
            return "\(timeIndex):00"
        
    

【问题讨论】:

您应该创建一个minimal reproducible example,因为您甚至没有显示视图代码。但是,我怀疑您在正文中使用timeShown,因此您也尝试在正文中设置@State 属性。这会创建一个无限循环,因为设置 @State 会触发另一个视图更新。 【参考方案1】:

代码正在改变startIndexendIndex 状态,这是派生timeShown 的副作用。大概是在 View 的主体中使用的,因此将在系统尝试渲染 View 时确定。

因此,正如消息所述,视图依赖于决定渲染什么的状态在它的脚下发生了变化,而它正在渲染它的中途,这很糟糕。

在 SwiftUI Lab here987654321@

要解决此处的问题,请重构代码以显式侦听当前预期侦听的任何隐式状态更改。然后当检测到这种情况时,根据需要在更改处理程序中设置startIndexendIndex

正如其他人所提到的,这里没有足够的代码来准确计算出需要什么,但如果解决方案看起来不像......

var foo: some View 
    ... displays timeShown somewhere in in here

.onChange(of: manager.selectedDateByIndex, perform:  newValue in
    if newValue != 0 
        startIndex = 6
        endIndex = 30
     else 
        startIndex = hour
        endIndex = 24
    
)
 

【讨论】:

以上是关于SwiftUI 计算属性显示“在视图更新期间修改状态,这将导致未定义的行为。”错误的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - @Binding 到访问 ObservableObject 属性内的值的计算属性会复制变量吗?

为 Swiftui 视图转换 @State 的计算属性

在 SwiftUI 视图中设置计算属性无法编译

SwiftUI 中子结构的计算属性未更新

SwiftUI:具有计算属性的 ObservableObject

SwiftUI 中已发布的计算属性未更新