簡體   English   中英

SwiftUI DocumentGroup 並切換到后台

[英]SwiftUI DocumentGroup and switching to background

我已經為“基於文檔的應用程序”制作了一個基於新 SwiftUI 多平台目標的應用程序。 但是,我面臨着奇怪的問題。 只要應用程序在前台,它就可以正常工作。 如果通過任務切換將其移至后台,然后再次移至前台,則會將突變保存到文檔中,但 SwiftUI 視圖不會收到突變。 因此,每當您在 UI 中按下一個更改文檔的按鈕時,當您從磁盤重新加載文檔時,您會看到沒有發生任何變化。

所以我在想,我使用 ObservedObjects,一旦我移動到后台,它們可能會被踢出 memory。 這可能是我的錯誤的原因嗎?

但后來我在 App 結構中添加了一個打印行。

import SwiftUI

@main
struct MyApp: App {

    fileprivate func myLogging(_ file: FileDocumentConfiguration<MyDocument>) -> some View {
        print("""
                    IT IS CALLED
            """)

        return MainView().environmentObject(BindingWrapper(file.$document))
    }

    var body: some Scene {
        DocumentGroup(newDocument: MyDocument()) { (file) in
            return myLogging(file)
        }.commands { AppCommands() }
    }
}

猜猜看……這個打印總是在渲染突變之前執行。 這是有道理的。 因為file.$document是一個綁定,如果你做了一個 mutating 操作,綁定會警告 Apple 文件是臟的,但它也會使整個層次結構失效。 一旦發生錯誤,此日志記錄仍將打印!

所以在MainView().environmentObject(BindingWrapper(file.$document))我假設一切都是從頭開始創建的。 BindingWrapper 是一個自定義的 class,用於轉換可觀察的 object 中的綁定。 這是我擔心的對象之一,他們可能會被釋放。 但如果它們是新創建的……它們應該一直在那里,對吧? 順便說一句,這個 object 歸環境所有。 所以它不應該被釋放。

所以,現在我被困住了。 Apple 是否在綁定 / ObservedObjects 上做了一些巧妙的緩存,即使我認為一切都是新創建的,也會將舊對象注入我的視圖層次結構中?

嘗試將任何連線/實例化移動到文檔組的第一個視圖。 如果該視圖包含您希望共享文檔 window 的生命周期的 StateObject,它們將不會被重建。

在下面的示例中,一個 WindowStore 被容納為一個 @StateObject,如所述。 App 中的 RootStore 創建了 WindowStore,其中包括自動售貨服務並將其注冊到 windows 的托管數組中。 兩者都可以啟用您的日志服務。 (對我來說,當 @FocusedValue 失敗時,該數組幫助 WindowGroups 對特定文檔進行操作(即,最頂層的文檔不再是關鍵窗口)。)

@main
struct ReferenceFileDoc: App {
    
    @StateObject var root: RootStore
    
    var body: some Scene {
        DocumentGroup { ProjectDocument() } editor: { doc in
            DocumentGroupRoot(
                window: root.makeWindowStore(doc.document),
                factory: SwiftUIFactory(root, doc.document)
            )
            .environmentObject(doc.document)
            .environment(\.documentURL, doc.fileURL)
            .injectStores(from: root)
        }.commands { Menus(root: root) }

    .... other scenes ...
struct DocumentGroupRoot: View {
    
    @EnvironmentObject var doc: ProjectDocument
    @Environment(\.undoManager) var undoManager
    @Environment(\.documentURL) var url

    @StateObject var window: WindowStore
    @StateObject var factory: UIFactory
    
    var body: some View {
        passUndoManagerToDocument()
        factory.reference(window)
        return DocumentWindow(vm: factory.makeThisVM()) // Actual visible window
            .focusedValue(\.keyWindow, window)
            .focusedValue(\.keyDocument, doc)
            .onAppear { /// Tasks }
            .reportHostingNSWindow { [weak window] in
                window?.setWindow($0)
            }
            .onChange(of: url) { [weak window] in window?.setFileURL($0) }
            .environmentObject(/// sub-state stores from WindowStore)
            .environmentObject(window)
            .environmentObject(factory)
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM