Swift 在 iOS 应用程序中未 运行 正确组合

Swift combine not running properly in iOS app

所以我是 swift 的新手,所以我可能理解错了。

我正在学习使用 combine,所以我使用 playground 以这样的间隔记录

var cancellable:AnyCancellable? = Timer.publish(every: 1, on: .main, in: .default)
.autoconnect()
.sink {
    print([=13=])
}

PlaygroundPage.current.needsIndefiniteExecution = true

它非常简单,而且工作方式与我预期的一样,每秒打印一条日志。

现在,当我在 Xcode 中创建一个新的 iOS 项目时,它似乎不起作用,我也不知道为什么。在一个空白项目中,我只是在 ContentView

中添加了这个
struct ContentView: View {
    func test() {
        var cancellable: AnyCancellable?
        cancellable = Timer.publish(every: 1, on: .main, in: .default)
        .autoconnect()
        .sink {
            print([=14=])
        }
    }
    
    var body: some View {
        VStack {
            Text("Hello, world!")
                .padding()
        }
    }
    
    init() {
        test()
    }
}

突然不行,log也不打印了。我敢肯定这是我不理解的愚蠢行为,但我一直在研究这个问题。我的真实情况是网络调用不是 运行,所以我尝试尽可能地简化,这是我能得到的最简单的。

感谢任何帮助!

谢谢!

您没有调用函数。在这种情况下,您需要在视图中将可取消设置为 属性。

这里发生了几件事:

  1. 您的 cancellable 立即超出范围,因此未被存储。在您的视图中将其更改为 @State 属性。

  2. SwiftUI 对视图 init() 中 can/can 不会发生的事情非常挑剔。处理此问题的两种选择: a) 将其移动到 onAppear b) 将其移动到 @ObservableObject

    的 init()

工作示例:

struct ContentView: View {
    @State var cancellable : AnyCancellable?
    
    func test() {
        cancellable = Timer.publish(every: 1, on: .main, in: .default)
        .autoconnect()
        .sink {
            print([=10=])
        }
    }
    
    var body: some View {
        VStack {
            Text("Hello, world!")
                .padding()
        }.onAppear {
            test()
        }
    }
}

ObservableObject 版本:

class ViewModel : ObservableObject {
    private var cancellable : AnyCancellable?
    
    init() {
        cancellable = Timer.publish(every: 1, on: .main, in: .default)
        .autoconnect()
        .sink {
            print([=11=])
        }
    }
}

struct ContentView: View {
    var vm = ViewModel()
    
    var body: some View {
        VStack {
            Text("Hello, world!")
                .padding()
        }
    }
}