Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 是否强制publisher发布更新?_Swift_Swiftui_Combine - Fatal编程技术网

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