【问题标题】:'self' captured by a closure before all members were initialized error in Timer Publisher在 Timer Publisher 中的所有成员初始化错误之前由闭包捕获的“self”
【发布时间】:2020-03-17 11:31:33
【问题描述】:

这适用于 MacOS。我正在尝试将 Timer 发布者封装到一个类中,这样我就可以添加自包含的功能。我有以下代码


import Combine


class MyTimer{
    let subscription: AnyCancellable
    var count: Int = 0

    init(){
       subscription = Timer.publish(every:0.1,on:.main,in:.default).autoconnect()
          .sink{_ in
             self.count += 1
             print(self.count)
         }
    }

    deinit {
        subscription.cancel()     
        print("done")
    }

}

类是这样调用的:

let timer = MyTimer()

并通过将计时器设置为 nil 来停止。

不幸的是我得到了

在所有成员初始化之前被闭包捕获的'self'

错误。如果我删除接收器中的count 位,它可以正常工作。我尝试将init 的内容移动到start() 方法中,并且该方法有效,但是当计时器设置为nil 时,从未调用过deinit()。我目前正在使用全局计数作为解决方法,但这并不是很令人满意,因为更多代码将进入此类。任何提示我该怎么做?我看过其他一些类似的问题,但似乎没有一个是相关的。谢谢!

【问题讨论】:

  • 好的方法是确实将init 的内容移动到start() 或类似方法。你只需要记住在闭包中弱捕获self - { [weak self] in ... }。您的 deinit 因保留周期而未被调用,而弱捕获 self 将解决该问题。
  • 请不要放回swiftui标签,因为它与这个问题完全无关。这个问题纯粹是关于Combine的,里面没有SwiftUI代码。
  • 好的,感谢您的帮助!我认为这是一个阻止调用 deinit() 的保留周期。我的下一个问题是,目前除了简单的闭包之外,我完全一无所知,所以我不确定如何在 sink 中编写 [weak self] 位。如果我写:你能说明那部分是怎么写的吗?谢谢!
  • Dávid Pásztor 对不起!我没有意识到有人删除了它。

标签: swift closures combine


【解决方案1】:

好的,多亏了几张海报,我明白了。我将 init 的内容移动到 start() 函数中,如下所示:

class MyTimer{
    var subscription: AnyCancellable?
    var count: Int = 0


    init(){
    }

    func start(){
        subscription = Timer.publish(every:0.1, on:.main,     in:.default).autoconnect()
            . sink{ [weak self] _ in
                    guard let self = self else { return }
                    self.count += 1
                    print(self.count)
                }

    }

    deinit {
        subscription?.cancel()
        print("done")
    }
}

感谢所有帮助过的人

【讨论】:

  • 无需在您的deinit 中调用subscription.cancel,Combine 会自动为您完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-18
  • 1970-01-01
  • 2020-05-31
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多