Swift 是否强制publisher发布更新?
在我的Swift 是否强制publisher发布更新?,swift,swiftui,combine,Swift,Swiftui,Combine,在我的ViewModel的init()中,我有两个订阅者 第一个订阅DataProvider()中的下载数据,并用结果更新downloadeData。这会进行API调用,通常需要几秒钟才能发布数据 第二个应用程序订阅$savedData,然后仅使用savedData和下载数据中包含的数据更新filteredData数组 问题是downloaddedata需要时间下载,而savedData是即时的(它实际上在核心数据中)。下载后,我想强制更新上面的第二个观察者($savedData),以相应地更新
ViewModel
的init()
中,我有两个订阅者
DataProvider()
中的下载数据,并用结果更新downloadeData
。这会进行API调用,通常需要几秒钟才能发布数据$savedData
,然后仅使用savedData
和下载数据中包含的数据更新filteredData
数组
downloaddedata
需要时间下载,而savedData
是即时的(它实际上在核心数据中)。下载后,我想强制更新上面的第二个观察者($savedData
),以相应地更新过滤器数据
有没有办法手动强制发布者发布值?在observedObject上,我们可以调用objectWillChange.send()
,但是有类似的东西我可以调用$savedData
?
免责声明:这是我的应用程序的超级简化版本。请不要包含更改层次结构的答案。我还意识到,我可以在$allCoins上添加另一个出版商,以模仿$savedData上的出版商,但我宁愿强制更新$savedData。谢谢
导入快捷界面
结构测试视图:视图{
@StateObject var vm=ViewModel()
var body:一些观点{
VStack{
ForEach(vm.filteredData,id:\.self){中的用户
文本(用户)
}
}
}
}
结构测试视图\u预览:PreviewProvider{
静态var预览:一些视图{
TestView()
}
}
进口联合收割机
类ViewModel:ObservableObject{
@已发布的var downloadedData:[字符串]=[]
@已发布的变量savedData:[字符串]=[]
@已发布的变量filteredData:[字符串]=[]
var cancelables=Set()
@已发布的var provider=DataProvider()
init(){
//当这篇文章发表时。。。
//我可以强制发布/更新savedData吗?
提供者。$data
.assign(发送至:\.downloadeData,发送至:self)
//这里?
.store(在:&可取消项中)
$savedData
.map{(已保存)->[String]位于
返回中的saved.map{(savedItem)->字符串
返回self.downloadeData.contains(savedItem)?savedItem:“否”
}
}
.assign(到:\.Filteredata,在:self上)
.store(在:&可取消项中)
getSavedData()
}
func getSavedData(){
savedData=[“一”、“二”]
}
}
类数据提供程序:ObserveObject{
@已发布的变量数据:[String]=[]
init(){
getData()
}
func getData(){
//模拟api调用
DispatchQueue.main.asyncAfter(截止日期:.now()+2.0){
self.data.append(内容:[“一”,“二])
}
}
}
您可以订阅下载的数据并将其分配给保存的数据:
$downloadedData
.assign(to: \.savedData, on: self)
.store(in: &cancellables)
请参阅以下链接,因为在将self
作为参数传递时,使用assign(to:on:)
会导致内存泄漏
您的其他订阅也使用self
作为参数调用assign(to:on:)
,最好在链接中实现解决方案,因为它可以在整个应用程序中解决此问题。您可以订阅下载的数据并将其分配给保存的数据:
$downloadedData
.assign(to: \.savedData, on: self)
.store(in: &cancellables)
请参阅以下链接,因为在将self
作为参数传递时,使用assign(to:on:)
会导致内存泄漏
您的其他订阅也使用self
作为参数调用assign(to:on:)
,最好在链接中实现该解决方案,因为它可以解决整个应用程序中的此问题。您可能以错误的方式思考此问题
首先,让我们正确使用术语。您在init
中订阅了两个发布者。每当它们各自的属性发生更改时,这两个发布服务器都会发出一个值
当savedData
或downloadedData
发生更改时,您似乎想做的是更新filteredData
。因此,与“强制更新”不同,您应该订阅在需要时发出所需内容的发布者。您可以使用CombineTest
来实现这一点:
$savedData.combineLatest(provider.$data)
.map { (saved, downloaded) in
//...
}
.sink { [weak self] value in
self?.filteredData = value
}
.store(in: &cancellables)
(不要使用assign
-它会创建一个对self
的强引用;相反,将sink
与弱self
一起使用)您可能以错误的方式思考问题
首先,让我们正确使用术语。您在init
中订阅了两个发布者。每当它们各自的属性发生更改时,这两个发布服务器都会发出一个值
当savedData
或downloadedData
发生更改时,您似乎想做的是更新filteredData
。因此,与“强制更新”不同,您应该订阅在需要时发出所需内容的发布者。您可以使用CombineTest
来实现这一点:
$savedData.combineLatest(provider.$data)
.map { (saved, downloaded) in
//...
}
.sink { [weak self] value in
self?.filteredData = value
}
.store(in: &cancellables)
(不要使用assign
-它创建了一个对self
的强引用;而是使用sink
与弱self
一起使用)谢谢你的回复,但这不是我要的。谢谢你的回复,但这不是我要的。是的!!!这就是我要找的。非常感谢。在iOS 14中,苹果推出了安全使用的iOS。所以你可以做.assi