Avatar
final class Integer: Hashable, CustomStringConvertible { let value: Int init(_ value: Int) { self.value = value } static func == (lhs: Integer, rhs: Integer) -> Bool { true } func hash(into hasher: inout Hasher) { 42.hash(into: &hasher) } var description: String { value.description } } に変えて、 AView(value: Integer(Bool.random() ? 1 : 2)) にしたら更新されなくなった。
7:16 AM
Integer 変更前は AView(value: Integer(Bool.random() ? 1 : 2)) で更新された。
7:17 AM
参照型はビット比較するとアドレスが異なる場合に diff 発生してしまうから Equatable を見てる??
7:22 AM
import SwiftUI struct ContentView2: View { @ObservedObject private var counter: Counter = .shared var body: some View { print("ContentView2.body") return VStack { HStack { Text("\(counter.count)") Button("+") { self.counter.increment() } } AView(value: Box<Double>(.nan)) .padding() .border(Color.gray, width: 1) .padding() } } } private struct AView<Value: CustomStringConvertible>: View { let value: Value var body: some View { print("AView.body") return VStack { HStack { Text("\(Counter.shared.count), \(value.description)") Button("+") { Counter.shared.increment() } } BView(value: value) .padding() .border(Color.gray, width: 1) .padding() } } } private struct BView<Value: CustomStringConvertible>: View { let value: Value var body: some View { print("BView.body") return HStack { Text("\(Counter.shared.count), \(value.description)") Button("+") { Counter.shared.increment() } } } } private final class Counter: ObservableObject { @Published private(set) var count: Int = 0 func increment() { count += 1 } static let shared: Counter = .init() } final class Box<Value>: Equatable, CustomStringConvertible where Value: Equatable, Value: CustomStringConvertible { let value: Value init(_ value: Value) { self.value = value } static func == (lhs: Box<Value>, rhs: Box<Value>) -> Bool { lhs.value == rhs.value } var description: String { value.description } } ↑これだと常に更新される。やっぱ == が見られてるっぽい。
7:23 AM
AView(value: Box<Double>(.nan))AView(value: Box<Double>(42)) に変更すると更新されなくなる。