我在解决一个bug时遇到了些困难,不知道该如何解决或者去哪里寻找答案。
问题出现在我尝试将一个视图(它持有一个NavigationView)从视图层级中移除时。它崩溃并显示:Thread 1: EXC_BAD_ACCESS (code=1,address=0x10)
在尝试使用Sanitizer调试器之后,我得到了这个输出:*** -[_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()
}
}
}
RootView
struct RootView: View {
@StateObject private var viewModel = RootViewModel()
var body: some View {
if !viewModel.loggedIn {
WelcomeView()
} else {
ContentView()
}
}
}
RootViewModel
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()
}
}
}
}
ContentView
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)
}
}