簡體   English   中英

從視圖層次結構中刪除 SwiftUI NavigationView 會導致 EXC_BAD_ACCESS

[英]Removing SwiftUI NavigationView from view hierarchy result in EXC_BAD_ACCESS

我正在與一個錯誤作斗爭,我似乎無法解決它,或者在哪里進一步尋找。

當我嘗試從視圖層次結構中刪除視圖(包含 NavigationView)時,就會出現問題。 它崩潰了: Thread 1: EXC_BAD_ACCESS (code=1, address=0x10)

在試用了消毒劑后,我在調試器中得到了這個 output: *** -[_TtGC7SwiftUI41StyleContextSplitViewNavigationControllerVS_19SidebarStyleContext_ removeChildViewController:]: message sent to deallocated instance 0x10904c880

這讓我發現它是以某種方式導致它的 NavigationView 。 但我仍然不知道如何從這里出發。

此問題僅發生在真實設備上,它在模擬器中運行良好,您可能必須登錄,然后在崩潰發生之前注銷並重新登錄幾次。

我用示例制作了一個示例應用程序: https://github.com/Surferdude667/NavigationRemoveTest

代碼如下:

NavigationRemoveTestApp

@main
struct NavigationRemoveTestApp: App {
    var body: some Scene {
        WindowGroup {
            RootView()
        }
    }
}

根視圖

struct RootView: View {

    @StateObject private var viewModel = RootViewModel()

    var body: some View {
        if !viewModel.loggedIn {
            WelcomeView()
        } else {
            ContentView()
        }
    }
}

根視圖模型

class RootViewModel: ObservableObject {

    @Published var loggedIn = false

    init() {
        LogInController.shared.loggedIn
            .receive(on: DispatchQueue.main)
            .assign(to: &$loggedIn)
    }
}

歡迎查看

struct WelcomeView: View {
    var body: some View {
        NavigationView {
            VStack {
                Text("Welcome")
                NavigationLink("Go to login") {
                    LogInView()
                }
            }
        }
    }
}

登錄查看

struct LogInView: View {
    var body: some View {
        VStack {
            Text("Log in view")
            Button("Log in") {
                LogInController.shared.logIn()
            }
        }
    }
}

內容視圖

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Content view")
            Button("Log out") {
                LogInController.shared.logOut()
            }
        }
    }
}

登錄控制器

import Combine
class LogInController {

    static let shared = LogInController()

    var loggedIn: CurrentValueSubject<Bool, Never>

    private init() {
        self.loggedIn = CurrentValueSubject<Bool, Never>(false)
    }

    func logIn() {
        self.loggedIn.send(true)
    }

    func logOut() {
        self.loggedIn.send(false)
    }
}

我找到了一些解決方案。

  1. 要么將 if 語句包裝在帶有NavigationViewRootView中,而不是將NavigationView放在實際視圖中,它都可以工作。 然而,這不是很方便,因為現在所有內容都包含在 NavigationView 中。

  2. 用新的 iOS 16 NavigationStack替換 NavigationView 也解決了這個問題。

暫無
暫無

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

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