错误:转义闭包捕获变异的“自我”参数
Posted
技术标签:
【中文标题】错误:转义闭包捕获变异的“自我”参数【英文标题】: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
【参考方案1】:
我认为这与 @State 属性无关,但与您使用的是 @escaping 闭包这一事实有关。如果在闭包中使用 self ,转义闭包会导致强引用循环。请参阅 link 中解释 @escaping 闭包的精彩文章。
亲切的问候, Mac用户T
【讨论】:
结构体没有引用循环这种东西 好吧,John,你确定 Timer 和 DispatchQueue 也是结构体吗?它们是 Objective-C 的残余。 Timer 和 DispatchQueue 不是结构体。问题中的ViewA: View
是一个结构体。以上是关于错误:转义闭包捕获变异的“自我”参数的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 3.0 中的转义闭包中改变自我(结构/枚举)