首页
学习
活动
专区
圈层
工具
发布
    • 综合排序
    • 最热优先
    • 最新优先
    时间不限
  • 来自专栏肘子的Swift记事本

    StateObject 与 ObservedObject

    ObservedObject 和 StateObject 两者都保存了视图与可观察对象的订阅关系,在视图存续期内,它们都不会主动取消这个订阅,但 ObservedObject 无法确保可观察对象是否会由于被销毁而提前取消订阅 请阅读 避免 SwiftUI 视图的重复计算[3] 一文,了解更多有关 DynamicProperty 的实现细节ObservedObject 偶尔出现灵异现象的原因如果使用类似 @ObservedObject 这也是 @ObservedObject var testObject = TestObject() 并非总会失效的原因。 ObservedObject 的正确用法为:@ObservedObject var testObject:TestObject 。 总结StateObject 和 ObservedObject 是我们经常会使用的属性包装器,它们都有各自擅长的领域。

    3.2K20编辑于 2023-03-08
  • 来自专栏Dotnet9

    SwiftUI @State @Published @ObservedObject 深入理解和使用

    2.0 但是需要 IOS 14 支持,多数现在还用的是IOS 13 所以很多不完善的东西都用SwiftUIX 以及各种库代替,bug也是层出不穷 2.下面是鄙人对 @State @Published @ObservedObject @Published + @ObservedObject 介绍 @Published是SwiftUI最有用的包装之一,允许我们创建出能够被自动观察的对象属性,SwiftUI会自动监视这个属性,一旦发生了改变 比如我们定义的数据结构Model,前提是 @Published 要在 ObservableObject 下使用 然后用 @ObservedObject 来引用这个对象,当然@State 不会报错,但是无法更新 var workModel:WorkModel = WorkModel() @ObservedObject var userModel:UserModel = UserModel var workModel:WorkModel = WorkModel() @ObservedObject var userModel:UserModel = UserModel

    4.3K10发布于 2021-12-01
  • 来自专栏肘子的Swift记事本

    @StateObject 研究

    通过代码了解不同 我通过下面的代码来详细阐述一下 @StateObject 和 @ObservedObject的不同表现。 在这个测试中,@ObservedObject创建的实例生命周期长于当前的View。 在这个测试中,@ObservedObject创建的实例生命周期和View是一致的。 尽管或许上面例子的某种特性可能让你觉得ObservedObject可以完成某些特殊需求(比如测试2),但我们无法保证苹果在之后不改变ObservedObject的运行机理,从而改变当前的结果。 通过下述代码,使用@StateObject同样可以得到测试2中ObservedObject的运行效果。

    1.7K40编辑于 2022-07-28
  • 来自专栏肘子的Swift记事本

    探讨 SwiftUI 中的几个关键属性包装器

    详情请阅读 StateObject 与 ObservedObject[11] 。 } } } // 子视图 struct MySubView: View { // 使用 @ObservedObject 引入外部的 ObservableObject 实例 @ObservedObject 它对视图的更新触发条件与 @StateObject 和 @ObservedObject 一样。 与 @ObservedObject 一样, @EnvriomentObject 支持动态切换关联的实例。 @StateObject 通常用于创建和维护实例,而 @ObservedObject 用于引入和响应已存在的实例。

    3.4K10编辑于 2023-12-21
  • 来自专栏Swift社区

    如何让 SwiftUI 的列表变得更加灵活

    作为起点,假设我们正在处理以下 ArticleList 视图,该视图使用 ArticleListViewModel 来呈现文章列表: struct ArticleList: View { @ObservedObject 样式应用于列表中,我们不需要拼出整个 InsetGroupedListStyle 名称,而是可以简单地将其称为 .insetGrouped: struct ArticleList: View { @ObservedObject 然后,让我们使用另一个新功能,集合元素绑定,让系统自动为我们的 articles 数组中的每个元素创建一个可变绑定: struct ArticleList: View { @ObservedObject 在列表中使用 refreshable 修饰符就可以完成,然后使用该修饰符的闭包 await 调用视图模型的异步 reload 方法: struct ArticleList: View { @ObservedObject 还有另外一个 API 用于控制部分分隔符的外观颜色,可以使用自定义颜色为分隔符设置颜色——代码如下: struct ArticleList: View { @ObservedObject var

    6.4K41发布于 2021-11-26
  • 来自专栏Swift社区

    SwiftUI 状态管理系统指南

    其中一个机制是ObservableObject协议,当它与ObservedObject属性包装器结合时,我们可以设置与我们视图层之外管理的引用类型的绑定。 有了上面的类型,现在让我们回到ProfileView,让它观察新的UserModelController的实例,作为一个ObservedObject,而不是用一个State属性包装器来跟踪我们的用户模型 除了 "迫使 "我们在代码库中建立一个更明确的依赖关系图之外,原因是一个标有ObservedObject的属性并不意味着对这个属性所指向的对象有任何形式的所有权。 把StateObject和ObservedObject看作是State和Binding的参考类型,或者SwiftUI版本的强和弱属性。 这是通过使用environmentalObject修饰符完成的,例如,像这样: struct RootView: View { @ObservedObject var theme: Theme

    6.5K20编辑于 2022-07-05
  • 来自专栏学海无涯

    SwiftUI-数据流

    View 内部产生的,这些数据有可能是一些本地存储的数据,也有可能是网络请求的数据,这些数据默认是与 SwiftUI 没有依赖关系的,要想建立依赖关系就要用 ObservableObject,与之配合的是@ObservedObject Published修饰需要监听的属性,一旦变化就会发出通知,它是发布者 @Published var address = "" } struct ContentView: View { @ObservedObject var User = User() // @ObservedObject修饰ObservableObject var body: some View { } } 案例 class UserSettings 使用基本与@ObservedObject一样,但@EnvironmentObject突出强调此数据将由某个外部实体提供,所以不需要在具体使用的地方初始化,而是由外部统一提供。 @ObservedObject、 @EnvironmentObject 一般修饰的都是 View 外部的数据: 系统级的消息 网络或本地存储的数据 界面之间互相传递的数据

    11.2K20发布于 2020-02-18
  • 来自专栏学海无涯

    SwiftUI-MVVM

    Identifiable { let id: UUID = UUID() let name: String } View struct ContentView: View { @ObservedObject View 中的@ObservedObject收到通知后驱动 UI 更新。 View 中的@ObservedObject收到通知后驱动 UI 更新。

    3.5K41发布于 2020-06-02
  • 来自专栏肘子的Swift记事本

    @State 研究

    SwiftUI中提供了诸如 @State ObservedObject EnvironmentObject等来创建应对不同类型、不同作用域的状态形式。 我们可以绑定到多种类型,包括 State ObservedObject 等,甚至还可以绑定到另一个Binding上面。Binding本身就是一个Getter和Setter的封装。 我们可以用另一段代码来分析编译器对 ObservedObject 的反应。 由此可以推测,SwiftUI对于ObservedObject采用了不同的依赖创建时机,只要声明,无论body里是否有需要,在ObservableObject的objectWillChange产生send 因此ObservedObject很可能是在初始化MainView的时候建立的依赖关系。 之所以花气力来判断这个问题,因为这两种创建依赖的时机的不同会导致View更新效率的巨大差异。

    3.7K20编辑于 2022-07-28
  • 来自专栏代码手工艺人

    轻量级KVO[译]

    property (nonatomic, weak) id target; @property (nonatomic) SEL selector; @property (nonatomic, weak) id observedObject selector:(SEL)selector { if (self) { self.target = target; self.selector = selector; self.observedObject clang diagnostic pop } } } 最后在dealloc方法中移除观察者对象: - (void)dealloc { id strongObservedObject = self.observedObject

    67730发布于 2021-09-07
  • 来自专栏肘子的Swift记事本

    避免 SwiftUI 视图的重复计算

    Storage { // 通过内部定义的枚举来标注视图是否已经被加载、数据是否已被数据池托管 case initially(() -> ObjectType) case object(ObservedObject _DynamicPropertyBuffer, container: _GraphValue<V>, fieldOffset: Int, inputs: inout _GraphInputs) } @ObservedObject @ObservedObject var store = Store() // 每次创建视图类型实例,都会重新创建 Store 实例 由于 SwiftUI 会不定时地创建视图类型的实例( 非加载视图 ), 每次创建的过程都会重新创建一个新的引用对象,因此假设使用上面的代码( 用 @ObservedObject 创建实例 ),让 @ObservedObject 指向一个不稳定的引用实例时,很容易出现一些怪异的现象 类型的情况在 @ObservedObject、@Environment 上也会出现: struct MyEnvKey: EnvironmentKey { static var defaultValue

    11K81编辑于 2022-08-03
  • 来自专栏肘子的Swift记事本

    ObservableObject研究

    章节中,我们通过了一段代码进行过@State和@ObservedObject对于依赖注入时机的推测。 结果就是通过使用@ObservedObject或@EnvironmentObject进行的依赖注入,编译器没有办法根据当前View的具体内容来进行更精确的判断,只要你的View中进行了声明,依赖关系变建立了 struct MainView: View { @ObservedObject var store = AppStore() var body: some View { print 第三步 和ObservedObject说再见 只要我们的View还需要依赖单一数据源的State,前面我们做努力就都付之东流了。但坚持单一数据源的设计思路又是十分明确的。 由于任何状态的变化ObservedObject只有通过ObjectWillChangePublisher这一个途径来通知与其依赖的View,因此我们如果要解决这个问题,只能放弃使用ObservedObject

    3K60编辑于 2022-07-28
  • 来自专栏肘子的Swift记事本

    在 SwiftUI 中创建自适应的程序化导航方案

    store.backParent() } .buttonStyle(.bordered) } }}struct DetailView: View { @ObservedObject store.backParent() } } .buttonStyle(.bordered) } }}struct SplitView: View { @ObservedObject } else { Text("Empty") } } }}struct StackView: View { @ObservedObject info.rootID), Level \(info.level)") } } }}struct DetailInfoView: View { @ObservedObject : info.rootID)) .foregroundColor(.blue) } }}struct SideBarView: View { @ObservedObject

    5.6K30编辑于 2023-03-08
  • 来自专栏Swift社区

    TCA - SwiftUI 的救星?(一)

    虽然 SwiftUI 中提供了诸多状态管理的关键字或属性包装 (property wrapper),比如 @State、@ObservedObject 等,但是你很难说官方 SwiftUI 教程里关于数据传递 简单就可以列举一些: 复杂的状态修饰,想要”正常“使用,你至少必须要记住 @State,@ObservedObject,@StateObject,@Binding,@EnvironmentObject 在 SwiftUI 中,TCA 使用 ViewStore (它本身是一个 ObservableObject) 来通过 @ObservedObject 触发 UI 刷新。 作为 View,它通过 @ObservedObject 对这个 ViewStore 进行观察,并响应它的变更。 在 SwiftUI 中,body 的刷新是 SwiftUI 运行时通过 @ObservedObject 属性包装所提供的特性。现在这部分内容被包含在了 WithViewStore 中。

    4.1K30编辑于 2021-12-20
  • 来自专栏韦弦的偶尔分享

    在 Swift 中使用 async let 并发运行后台任务

    reset() { self.file = DataFile(id: 1, fileSize: 10) } } View: struct TestView1: View { @ObservedObject reset() { self.file = DataFile(id: 1, fileSize: 10) } } View: struct TestView2: View { @ObservedObject 20), DataFile(id: 3, fileSize: 5) ] } } View: struct TestView3: View { @ObservedObject 20), DataFile(id: 3, fileSize: 5) ] } } View struct TestView4: View { @ObservedObject

    2K20编辑于 2023-03-12
  • 来自专栏韦弦的偶尔分享

    如何在 Swift 中取消一个后台任务

    View: struct NaiveCancelView: View { @ObservedObject private var dataFiles: DataFileViewModel5 View: struct CancelFlagView: View { @ObservedObject private var dataFiles: DataFileViewModel6 View: struct CancelTaskView: View { @ObservedObject private var dataFiles: DataFileViewModel7 View: struct CancelTaskMultipleView: View { @ObservedObject private var dataFiles: DataFileViewModel8

    4K30编辑于 2023-03-12
  • 来自专栏韦弦的偶尔分享

    SwiftUI:使用 @EnvironmentObject 从环境中读取自定义值

    您已经了解了如何使用@State处理单个视图的局部状态,以及@ObservedObject如何使我们在视图之间传递一个对象,以便我们可以共享它。 如果我们使用@ObservedObject,则需要将我们的对象从每个视图传递到下一个视图,直到它最终到达可以使用该视图的视图E,这很烦人,因为B,C和D不在乎它。

    11.1K20发布于 2020-09-10
  • 来自专栏陈满iOS

    iOS开发·KVO用法,原理与底层实现: runtime模拟实现KVO监听机制(Blcok及Delgate方式)

    - (void)viewDidLoad { [super viewDidLoad]; ObservedObject * object = [ObservedObject new pragma mark - Observed By Block [object CM_addObserver: self forKey: @"observedNum" withBlock: ^(id observedObject - (void)viewDidLoad { [super viewDidLoad]; ObservedObject * object = [ObservedObject new

    2.3K31发布于 2018-09-10
  • 来自专栏肘子的Swift记事本

    SwiftUI 与 Core Data —— 数据定义

    0) }}创建 GroupCell 视图struct GroupCellView:View { @ObservedObject var group:C_Group var body: 当数据发生变化时,可以通知视图进行刷新因此无论如何,我们都应该在视图中保留托管对象的上述优点,如此,上面的代码将会演变成下面的模样:struct GroupCellViewRoot:View { @ObservedObject AnyConvertibleValueObservableObject考虑到 @ObservedObject 只能接受具体类型的数据( 无法使用 any ConvertibleValueObservableObject AnyConvertibleValueObservableObject(object: self) }}现在对 GroupCellViewRoot 视图进行如下调整:struct GroupCellViewRoot:View { @ObservedObject // 当前 Group 中包含的 Task 数量}创建 TodoGroupView( 此时已无需 TodoGroupViewRoot )struct TodoGroupView:View { @ObservedObject

    3K40编辑于 2023-03-08
  • 来自专栏肘子的Swift记事本

    SwiftUI 与 Core Data —— 安全地响应数据

    不过,通常我们在子视图中,会用 ObservedObject 来标注托管对象实例,以实时响应数据变动,因此如果我们将代码调整成正常的编写模式就能看出问题所在了:struct Cell:View { @ObservedObject var item:Item // 响应数据变化 @Environment(\.managedObjectContext) var viewContext var object.convertToValueType() }}如此一来,便可以通过在视图代码使用 if let 来保证不会出现上文提到的崩溃问题:public struct Cell: View { @ObservedObject perform: deleteItems)}// 模态视图.sheet(item: $item) { item in Cell(item: item)}struct Cell: View { @ObservedObject struct Cell: View { let item: Item // 无需使用 ObservedObject /* 如果使用的是 MockableFetchRequest ,则为

    4.5K20编辑于 2023-03-08
领券