SwiftUI中DocumentGroup偶现多次创建视图问题求助
SwiftUI DocumentGroup中视图多次初始化且onAppear触发异常问题
在SwiftUI应用中,通过.onAppear创建对象并添加数据时,每4-6次操作会出现一次对象被多次创建,且并非所有实例都会触发.onAppear的情况。经过调试简化代码后,在ContentView的初始化方法和TextDocument的读取方法中添加了打印日志:多数情况下打开文本文件时,只会打印一次"Read data"和"Create view",但每3-6次会出现一次"Read data"搭配三次"Create view"的情况,文件大小不影响该问题的出现频率。使用WindowView进行相同测试时,从未出现多次"Create view"的打印信息。
import SwiftUI import UniformTypeIdentifiers @main struct OneMoreTimeApp: App { var body: some Scene { DocumentGroup(newDocument: TextDocument()) { file in ContentView(document: file.$document) } } } struct ContentView: View { @Binding var document: TextDocument init(document: Binding<TextDocument>) { print("Create view") self._document = document } var body: some View { VStack { Text("Hello World") Text(document.data) } } } struct TextDocument: FileDocument { static var readableContentTypes : [UTType] {[.text]} var data: String init(text: String = "This is some text") { print("init data") self.data = text } init(configuration: ReadConfiguration) throws { print("read data") if let data = configuration.file.regularFileContents { self.data = String(decoding: data, as: UTF8.self) } else { throw CocoaError(.fileReadCorruptFile) } } func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { print("write data") let outData = Data(data.utf8) return FileWrapper(regularFileWithContents: outData) } }
怀疑这是Apple的Bug,但希望先确认自身代码是否存在问题。
复现步骤
- 启动应用
- 打开一个文本文件
- 等待10秒
- 确认"Create view"仅打印一次
- 关闭文本文件
- 重复步骤1-5十次,通常5次内即可复现问题
- 也可跳过步骤5,重复步骤2-4,但最多需要30次操作才能复现
测试环境
- iPad Pro(12.9英寸第三代),运行iOS16.2
- iPhone14 Pro Max,运行iOS16.2
- iPhone14模拟器
- 使用Xcode14.2构建,目标版本涵盖iOS14.7、15.6、16.0、16.1,均存在该问题
以下是更贴近实际场景的代码示例,其中自定义ObservableObject也会被多次创建:
import SwiftUI import UniformTypeIdentifiers @main struct OneMoreTimeApp: App { var body: some Scene { DocumentGroup(newDocument: TextDocument()) { file in ContentView(document: file.$document) } } } struct ContentView: View { @Binding var document: TextDocument @State var myObject = MyObject() init(document: Binding<TextDocument>) { print("Create view") self._document = document } var body: some View { VStack { Text("Hello World") Text("\(myObject.text)") Text(document.data) .onAppear{ print("onAppear - myObject is \(myObject.text)") myObject.text += " - onAppear" } } } } struct TextDocument: FileDocument { static var readableContentTypes : [UTType] {[.text]} var data: String init(text: String = "This is some text") { print("init data") self.data = text } init(configuration: ReadConfiguration) throws { print("read data") if let data = configuration.file.regularFileContents { self.data = String(decoding: data, as: UTF8.self) } else { throw CocoaError(.fileReadCorruptFile) } } func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { print("write data") let outData = Data(data.utf8) return FileWrapper(regularFileWithContents: outData) } } class MyObject : ObservableObject { static var numberOfObjects = 0 @Published var text = "none" init() { MyObject.numberOfObjects += 1 text = "Object number \(MyObject.numberOfObjects)" print("created \(text)") } deinit { print("killed \(text)") } }
内容的提问来源于stack exchange,提问作者DouglasGClarke
相关产品推荐
相关产品推荐

