В Swift это вылетает во время выполнения:
class EmptyData: BindableObject {
let didChange = PassthroughSubject<EmptyData, Never>()
}
struct RandomView : View {
@EnvironmentObject var emptyData: EmptyData
@EnvironmentObject var emptyData2: EmptyData
var body: some View {
Text("Hello World!")
}
}
и в SceneDelegate.swift
:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let window = UIWindow(frame: UIScreen.main.bounds)
// The emptyData variables are not initialized as seen below
window.rootViewController = UIHostingController(rootView: RandomView())
self.window = window
window.makeKeyAndVisible()
}
Поток 1: EXC_BAD_INSTRUCTION (код = EXC_I386_INVOP, субкод = 0x0)
Исправить проблему не так сложно, но довольно странно:
window.rootViewController = UIHostingController(rootView: RandomView().environmentObject(EmptyData()))
Так что здесь происходит? Я передаю EmptyData()
и SwiftUI решает, что и emptyData
, и emptyData2
должны быть инициализированы с одной и той же ссылкой на объект? Я могу также передать другие объекты среды, которые даже не существуют, в качестве переменных в экземпляре RandomView
:
window.rootViewController = UIHostingController(rootView: RandomView().environmentObject(EmptyData()).environmentObject(SomeData()))
И SwiftUI просто успешно работает, хотя SomeData()
нигде не используется в случае RandomView()
и должен вызвать ошибку времени компиляции, на мой взгляд.
Почему неинициализированные значения допускаются во время компиляции без их инициализации при инициализации объекта и почему мы можем свободно передавать экземпляры среды, ничего не делая с ними? Для меня это немного похоже на Javascript, мне понравилась сильная статическая безопасная типизация в Swift ... Я не сразу понимаю, почему инициализатор по элементам просто генерирует инициализатор, который принимает переменные среды в качестве параметра.