【问题标题】:Error: Escaping closure captures mutating 'self' parameter错误:转义闭包捕获变异的“自我”参数
【发布时间】:2021-03-25 12:57:40
【问题描述】:

我已经在 SO 上查看了有关此主题的其他问题(有很多),但没有一个解决与 @State 相关的此错误。我认为这正是@State 解决的问题!

这里是相关代码

 struct ViewA: View {
    @State private var startAnimation = false
    
    let width: CGFloat
    let height: CGFloat
    
    init(width: CGFloat, height: CGFloat) {
        self.width = width
        self.height = height
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            
            startAnimation = true //<--- The error is on this line
        }
            
        
    }
    
    var body: some View {
        Circle()
            .frame(width: width, height: height)
            .scaleEffect(CGSize(width: startAnimation ? 5.0 : 1.0 , height: startAnimation ? 5.0 : 1.0))
    }
}

有错误是Escaping closure captures mutating 'self' parameter

现在查看与此错误相关的其他 SO 问题让我知道此错误与 时间延迟更改有关 ...

【问题讨论】:

  • 为什么不使用 .onAppear() ? .onAppear() { DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { self.startAnimation = true } }
  • 好吧...现在为什么它在 .onAppear() 而不是 init() 内部工作??
  • init 用于初始化变量,而不是在某些时间段内更改变量值。
  • 正确,是用来初始化结构体的。每次需要重绘屏幕时,都会丢弃当前的 ViewA 并创建一个新结构,然后调用 init 来初始化自身。 OnAppear 应该会被调用一次。还有一种更 SwiftUI 的方式来延迟动画可能是:withAnimation(Animation.linear(duration: 0.5).delay(1)) { startAnimation = true }

标签: swift swiftui closures self


【解决方案1】:

我认为这与 @State 属性无关,但与您使用的是 @escaping 闭包这一事实有关。如果在闭包中使用 self ,转义闭包会导致强引用循环。请参阅 link 中解释 @escaping 闭包的精彩文章。

亲切的问候, Mac用户T

【讨论】:

  • 结构体没有引用循环这种东西
  • 好吧,John,你确定 Timer 和 DispatchQueue 也是结构体吗?它们是 Objective-C 的残余。
  • Timer 和 DispatchQueue 不是结构体。问题中的ViewA: View 是一个结构体。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-13
  • 2018-04-28
相关资源
最近更新 更多