这是我的模特:
class Channel: Identifiable, Decodable, ObservableObject {
var id = UUID()
var channelId = ""
var title = ""
var thumbnail = ""
@Published var thumbnailImage : UIImage?
enum CodingKeys: String, CodingKey {
//Keys not in the model
case snippet
case thumbnails
case high
//Keys in the model
case channelId
case title
case thumbnail = "url"
}
required init (from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let snippetContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .snippet)
let thumbnailsContainer = try snippetContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .thumbnails)
let highContainer = try thumbnailsContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .high)
self.title = try snippetContainer.decode(String.self, forKey: .title)
self.thumbnail = try highContainer.decode(String.self, forKey: .thumbnail)
self.channelId = try snippetContainer.decode(String.self, forKey: .channelId)
}
}
class ChannelStore: ObservableObject {
@Published var allChannels = [Channel]()
}
我有一个链接到ChannelStore的EnvironmentObject,并且一切正常。
问题是更改属性thumbnailImage时需要更新我的视图。 (由于来自网络通话,因此视图会在通话返回之前生成,并在此期间使用库存图片)。我尝试将发布的属性包装器添加到该属性,但是它什么也没做。
我认为我有:@EnvironmentObject var channelStore: ChannelStore
如何订阅由EnvironmentObject管理的属性更改?
修改
建议将Channel类更改为结构。我创建类的唯一原因是避免“无法分配给属性:'channel'是'let'常量:
for channel in channelStore.allChannels {
networking.setThumbnail(channel: channel) { image in
channel.thumbnailImage = image
}
}
最终评论
我可以使用下面提供的答案解决整个问题,并将for循环更改为以下内容:
for (index, var channel) in channelStore.allChannels.enumerated() {
networking.setThumbnail(channel: channel) { image in
channel.thumbnailImage = image
channelStore.allChannels[index] = channel
print("Images LOADED")
}
}
答案 0 :(得分:1)
如果您可以将Channel
设置为 struct :
struct Channel: Identifiable, Decodable { // <- replace `class` with `struct`
...
var thumbnailImage : UIImage? // <- remove `@Published`
}
然后,对thumbnailImage
的每次修改都会创建Channel
对象的新副本并触发@Published
中的ChannelStore
属性:
class ChannelStore: ObservableObject {
@Published var allChannels = [Channel]()
}