编译Xcode项目没有报错,但是预览视图时,提示:
CrashReportError: ImageSlim crashed
ImageSlim crashed. Check ~/Library/Logs/DiagnosticReports for crash logs from your application.
libdispatch.dylib:
BUG IN CLIENT OF LIBDISPATCH: trying to lock recursively
这是一个libdispatch 运行时致命错误,运行期在 SwiftUI Preview 启动阶段直接崩溃。
可能是初始化单例dispatch_once / static let shared)的过程中,发生了“递归加锁(re-entrant lock)”,libdispatch 检测到这一点后直接 abort 了进程。
根据报错日志信息,发现:
3 ??? _$s9ImageSlim0A14ArrayViewModelC6sharedACvau
8 ??? _$s9ImageSlim18WorkSpaceViewModelC6sharedACvau
14 ??? _$s9ImageSlim0A14ArrayViewModelC6sharedACvau
ArrayViewModel和WorkSpaceViewModel文件,初始化过程中存在循环依赖。
ArrayViewModel视图模型代码:
@MainActor
class ImageArrayViewModel: ObservableObject {
static let shared = ImageArrayViewModel()
var imageArray = ImageArrayViewModel.shared
}
WorkSpaceViewModel视图代码:
@MainActor
class WorkSpaceViewModel: ObservableObject {
static var shared = WorkSpaceViewModel()
var imageArray = ImageArrayViewModel.shared
}
ImageArrayViewModel.shared 在初始化时引用了 WorkSpaceViewModel.shared。
WorkSpaceViewModel.shared 在初始化时又引用了 ImageArrayViewModel.shared。
重复初始化导致递归锁定,造成死锁。
解决方案
1、延迟初始化:
@MainActor
class ImageArrayViewModel: ObservableObject {
static let shared = ImageArrayViewModel()
// 改为计算属性,避免在初始化时访问
var workSpaceVM: WorkSpaceViewModel {
WorkSpaceViewModel.shared
}
}
两个文件都改为计算属性,打破循环依赖。
2、移除单例模式,改为从SwiftUI中注入对象:
@MainActor
class ImageArrayViewModel: ObservableObject {
// 通过初始化器注入依赖
weak var workSpaceVM: WorkSpaceViewModel?
init(workSpaceVM: WorkSpaceViewModel? = nil) {
self.workSpaceVM = workSpaceVM
}
}
