onevcat / OneV-s-Den-Comments

0 stars 0 forks source link

2021/01/swiftui-state/ #7

Open utterances-bot opened 3 years ago

utterances-bot commented 3 years ago

关于 SwiftUI State 的一些细节 | OneV's Den

@State 基础

https://onevcat.com/2021/01/swiftui-state/

mustard-mh commented 3 years ago

感觉 SwiftUI 数据绑定这方面还是不够优雅

onevcat commented 3 years ago

@onecat-mh 是的...感觉还有非常多可以改进的地方。

hstdt commented 3 years ago

init(wrappedValue:)还有一个坑,它好像并没有被官方推荐使用。

You don't call this initializer directly. Instead, declare a property with the @State attribute, and provide an initial value;

以及还有一个init(initialValue value: Value)不知道他俩什么区别。不过目前用着也没什么问题。

onevcat commented 3 years ago

@hstdt 一般这种就是给你先挖个坑,类似免责声明?然后以后出问题了直接“不是我们的锅”..

99handmade commented 3 years ago

很少能读到含金量这么高的帖子 哈哈哈...

fatbobman commented 3 years ago

收益匪浅!请教一下,你是如何dump到更多的state中的私有资料的。我只能获取到_value 和 _location.

CrystDragon commented 3 years ago

现在最新的实现里对于 property wrapper 直接初始化的操作, 编译器可以正确识别为是对 backup value 的初始化. 所以self.number = number + 1应该是不会再报错了.

onevcat commented 3 years ago

现在最新的实现里对于 property wrapper 直接初始化的操作, 编译器可以正确识别为是对 backup value 的初始化. 所以self.number = number + 1应该是不会再报错了.

感谢指出。我找时间更新一下。

wyk111wyk commented 3 years ago

我发现我在第一次赋值的时候总是失败,第二次就成功了,不知道你遇到过类似的情况没有

clear731 commented 2 years ago

问答时间,你觉得 DetailView1 中的 Text 显示的会是什么呢?是 0,还是 100? 我的结果是100。文章需要更新啦。

clear731 commented 2 years ago

先执行的是init

zteshadow commented 1 year ago

上这段代码更容易理解

@propertyWrapper public struct State<Value> : DynamicProperty {
  internal var _value: Value
  internal var _location: SwiftUI.AnyLocation<Value>? // SwiftUI 托管数据池中的数据引用
  public init(wrappedValue value: Value)
  public init(initialValue value: Value) {
        _value = value // 创建实例时,只会暂存初始值
    }
  public var wrappedValue: Value {
    get  //  guard let _location else { return _value} ...
    nonmutating set // 只能改动 _location 指向的数据
  }

如果调用init函数, 是可以传入初始值的, 但是如果调用的是set如果_location还没有构造好, 那么就是无效的, 因此:

// case 1
struct DetailView1: View {
    @State private var number: Int

    init(number: Int) {
        self.number = number + 1 //调用init
    }
}

// case 2
struct DetailView1: View {
    @State private var number: Int = 0

    init(number: Int) {
        self.number = number + 1 //调用set, 此时_location为nil, 赋值无效
    }
}

case 1显示100, case 2显示0

littledogboy commented 1 year ago

对我很有帮助 这实在是 泰裤辣