向期望@Binding的参数传递@Published属性为何可正常运行?
底层运行逻辑说明
- 你传入的
$viewModel.isGalleryPresented本质不是Publisher,这是SwiftUI针对ObservableObject类型ViewModel提供的语法糖特性,实际返回的就是fullScreenCover要求的Binding<Bool>类型。 - 核心区别在于
$符号的作用对象,两种不同写法的返回类型完全不同:- 如果你写的是
viewModel.$isGalleryPresented:$作用于@Published修饰的属性,返回的才是你以为的Publisher<Bool, Never>类型,一般用于Combine数据流订阅。 - 你实际用的
$viewModel.isGalleryPresented:$作用于ViewModel实例本身,前提是该ViewModel在当前视图中是通过@StateObject/@ObservedObject/@EnvironmentObject这三个属性包装器声明的,此时$viewModel会返回属性包装器的投影值ObservedObject.Wrapper。
- 如果你写的是
- 该投影值类型被标记了**@dynamicMemberLookup**(动态成员查找),当你通过点语法访问它的成员属性时,系统会自动生成对应属性的双向绑定实例,等效于你手动写了完整的Binding构造代码:
// 你用的简化写法 .fullScreenCover(isPresented: $viewModel.isGalleryPresented) { GalleryPickerView() } // 等价于手动构造Binding .fullScreenCover(isPresented: Binding( get: { viewModel.isGalleryPresented }, set: { viewModel.isGalleryPresented = $0 } )) { GalleryPickerView() }
- 这个特性的设计目的就是简化从ObservableObject生成Binding的流程,避免每个需要绑定的属性都要手动写构造代码。
内容的提问来源于stack exchange,提问作者MegaManX
相关产品推荐
相关产品推荐

