我刚刚更新到 XCode 11.4,我的一些代码已经停止工作。我@Published在一个ObservableObject. 以前,当我更新结构上的属性时,该didSet方法会触发已发布的属性,但现在情况不再如此。在 Swift 的最新更新中,这种行为是否有可能被设计改变了?
这是一个简单的例子:
import SwiftUI
struct PaddingRect {
var left: CGFloat = 20
var right: CGFloat = 20
}
final class SomeStore : ObservableObject {
@Published var someOtherValue: String = "Waiting for didSet"
@Published var paddingRect:PaddingRect = PaddingRect() {
didSet {
someOtherValue = "didSet fired"
}
}
}
struct ObserverIssue: View {
@ObservedObject var store = SomeStore()
var body: some View {
VStack {
Spacer()
Rectangle()
.fill(Color.yellow)
.padding(.leading, store.paddingRect.left)
.padding(.trailing, …Run Code Online (Sandbox Code Playgroud) 有时我的视图模型使用@Published属性或 a PassthroughSubject,但我不希望它对外界可写。很简单,将其变成公共的AnyPublisher并将可写的保持为私有,如下所示:
class ViewModel {
@Published private var _models = ["hello", "world"]
var models: AnyPublisher<[String], Never> {
return $_models.eraseToAnyPublisher()
}
}
let viewModel = ViewModel()
viewModel.models.sink { print($0) }
Run Code Online (Sandbox Code Playgroud)
但是,如果您也希望能够“按需”读取该值怎么办?例如对于这种情况:
extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print(viewModel.models[indexPath.row])
}
}
Run Code Online (Sandbox Code Playgroud)
显然,上面的代码是行不通的。
我考虑过使用 a CurrentValueSubject,但它的值也是可写的,而且无论如何我都很难将 Publisher 变成 CurrentValueSubject 。
我当前的解决方案是在视图模型上添加类似的内容:
class ViewModel {
@Published private var _models = ["hello", "world"]
@Published var selectedIndex: Int?
var models: AnyPublisher<[String], Never> { …Run Code Online (Sandbox Code Playgroud)