You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 11:50:24