swift - 如何在swiftui中使两个具有可观察对象协议的类相互访问
问题描述
我有 2 个类,它们都符合可观察对象。MusicController,它充当创建的每个音乐对象的模型的一部分。当应用程序进入不同的状态(willEnterForeground)并相应地响应 UI 时,MusicCheck 充当 UI 的通知器。
我试图让两个类都能够相互访问。我将它们都设置为 EnvironmentObject,但这不允许它们在应用程序崩溃时相互访问,因为 MusicController 无权访问用于 MusicCheck 的 EnvironmentObject。
当音乐开始播放(在音乐控制器中)时,我想在 MusicCheck 中运行一个函数来更改变量值。如何允许 MusicController 类访问 MusicCheck 类?
class MusicController: ObservableObject {
@EnvironmentObject var musicCheck: MusicCheck
@Published var isPlaying = false
init() {
// play the music and setup other sound logic
// Change the variable in MusicCheck
}
}
class MusicCheck: ObservableObject {
@Published var isPlayingAfter = false
init() {
// perform logic for when the application willEnterForeground
}
}
解决方案
这是一个选项,onAppear
用于传递对 的引用musicCheck
:
class MusicController: ObservableObject {
@Published var isPlaying = false
var musicCheck : MusicCheck?
func setup(musicCheck : MusicCheck) {
self.musicCheck = musicCheck
//perform other setup logic
}
}
class MusicCheck: ObservableObject {
@Published var isPlayingAfter = false
init() {
// perform logic for when the application willEnterForeground
}
}
struct ContentView : View {
@StateObject private var musicCheck = MusicCheck()
@StateObject private var musicController = MusicController()
var body: some View {
VStack {
Text("Hello, world")
}.onAppear {
musicController.setup(musicCheck: musicCheck)
}
}
}
另一种可能性是使用单例模式。我对这种方法持谨慎态度,因为它可能导致难以测试的情况。另外,我经常看到的一个错误是人们创建了一个非单例实例并且对为什么他们有多个副本感到困惑——我使用 aprivate init
来避免这种情况。
class MusicController: ObservableObject {
@Published var isPlaying = false
init() {
MusicCheck.shared.someFunction()
}
}
class MusicCheck: ObservableObject {
static var shared = MusicCheck()
@Published var isPlayingAfter = false
private init() {
// perform logic for when the application willEnterForeground
}
func someFunction() {
}
}
struct ContentView : View {
@StateObject private var musicCheck = MusicCheck.shared
@StateObject private var musicController = MusicController()
var body: some View {
VStack {
Text("Hello, world")
}
}
}
推荐阅读
- asp.net-core-mvc - 有条件地处理 ASP.NET Core 中的拒绝访问行为
- javascript - 如何始终在单击的元素下方打开 contextMenu?
- javascript - 无法在谷歌表单中设置依赖下拉
- ios - Xamarin iOS 在 UIButton 中显示图像和文本
- c# - 为什么在运行时调用重载函数时会发生 RuntimeBinderException?
- android - Android 应用程序 Api 1 与 Api 2 中的 Google Pay
- java - Junit 测试用例 - 错误 - 预期状态:<200> 但原为:<500>
- c# - C# Winforms:当用户选择(鼠标单击)图表上的一个点时如何获取值
- wordpress - wordpress中两个div之间的间距问题
- wordpress - 无法在 wordrpess 中授权 Dropbox api