Xcode预览视图时,提示:
UpdateTimedOutError: Updating took more than 5 seconds
Updating a preview in ImageSlim.app (96036) took more than 5 seconds.
Preview.RegistryPreview | Registry-ImageRowView.swift#1[preview] [interactive(target: PreviewsPipeline.PreviewConfiguration.InteractionMode.InteractionTarget.local), from Editor(7650) for local, variant: nil, overrides: []]
分析代码得出的结论为,视图在渲染时会访问CustomImages对象的计算属性。
struct ImageRowView: View {
@ObservedObject var item: CustomImages // 图片对象
}
class CustomImages: ObservableObject {
// 计算属性涉及磁盘I/O,导致报错
var inputSize: Int {
if _inputSize == nil {
_inputSize = FileUtils.getFileSize(fileURL: inputURL)
}
return _inputSize ?? 0
}
}
这些属性同步执行磁盘IO + 图片解码操作,从而导致Preview进程里速度极慢,超过5秒。
核心问题:Preview模式中,禁止一切磁盘IO、图片解码、外部进程。
解决方案
1、给CustomImages添加判断,根据isPreview状态判断Preview模式:
static var isPreview: Bool {
ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1"
}
这段代码可以判断当前代码是否在SwiftUI的Xcode Preview(预览)环境中运行。
如果在SwiftUI预览中运行,Xcode会自动设置一个环境变量:
XCODE_RUNNING_FOR_PREVIEWS = 1
2、修改计算属性:
var inputSize: Int {
if Self.isPreview {
return _inputSize ?? 1_234_567
}
if _inputSize == nil {
_inputSize = FileUtils.getFileSize(fileURL: inputURL)
}
return _inputSize ?? 0
}
总结
问题的原因在于Xcode Preview被多次调用,而Preview模式禁用真实IO,因此执行代码出现超时的情况。
