Hello ReactiveSwift(5): 调试技术 ——(简译)

官方文档:
http://reactivecocoa.io/reactiveswift/docs/latest/index.html
实战项目:
https://github.com/JornWu/ZhiBo_Swift.git


一、整理Swift编译器错误

类型推断使编译器难以调试会错误,使用类型推断有两个潜在的地方出错:
1、定义类型推断的变量
2、使用类型推断的变量
在这两种情况下,错误与关于类型的不正确假设有关。这些问题对于ReactiveCocoa应用程序是常见的,因为它是关于数据和相关类型的操作。Swift编译器的当前状态可能导致误导类型错误,特别是当信号链中间发生错误时。
以下是类型错误情形的示例:

SignalProducer<Int, NoError>(value:42)
    .on(value: { answer in
        return _
    })
    .startWithCompleted {
        print("Completed.")
    }

上面的代码将不会在.startWithCompleted调用error:无法将类型'Disposable'的值转换为闭包结果类型'()'的时候出现以下错误。要找到实际的编译错误,链需要拆分。在每个步骤中添加关闭类型的显式定义:

let initialProducer = SignalProducer<Int, NoError>.init(value:42)
let sideEffectProducer = initialProducer.on(value: { (answer: Int) in
    return _
})
let disposable = sideEffectProducer.startWithCompleted {
    print("Completed.")
}

上面的代码因为存在error: cannot convert value of type '(Int) -> _' to expected argument type '((Int) -> Void)?'on闭包定义中,也不会编译。这给出足够的信息来定位意想不到的return _因为on结束不应该有任何返回值。

二、调试事件流

如README所述,流调试可能相当困难和乏味,因此我们提供logEvents操作。最简单的形式如下:

let property = MutableProperty<String>("")
...
let searchString = property.producer
    .throttle(0.5, on: QueueScheduler.main)
    .logEvents()

这将打印到标准输出的事件。对于大多数用例来说,这是足够的,将极大地帮助您了解您的流程。这种方法最大的问题是它将在Release模式下继续输出。这里你有两个选择:
注释操作://.logEvents()。这是最简单的方法,但它很容易出错,因为你最终会忘记这样做。
通过你自己的功能,并按照你的看法操纵输出。这是推荐的方法。
让我们看看如果我们不想在Release模式下打印出来的话,

func debugLog(identifier: String, event: String, fileName: String, functionName: String, lineNumber: Int) {
   // Don't forget to set up the DEBUG symbol (http://stackoverflow.com/a/24112024/491239)
   #if DEBUG
      print(event)
   #endif
}

你会:

let property = MutableProperty<String>("")
...
let searchString = property.producer
    .throttle(0.5, on: QueueScheduler.main)
    .logEvents(logger: debugLog)

我们也提供identifier参数。当您调试多个流并且不想丢失时,这很有用:

let property = MutableProperty<String>("")
...
let searchString = property.producer
    .throttle(0.5, on: QueueScheduler.main)
    .logEvents(identifier: "✨My awesome stream ✨")

还有一些情况,特别是热信号,当输出太多时。对于那些,您可以指定您感兴趣的事件:

let property = MutableProperty<String>("")
...
let searchString = property.producer
    .throttle(0.5, on: QueueScheduler.main)
    .logEvents(events: [.disposed]) // This will happen when `property` is released

推荐阅读更多精彩内容

  • 从2017年4月14日起,不再公开发布所写文字。深感自己文采水平有限,并不能带来高质量文章,所以决定以后更新的文章...
    听禅落雪阅读 84评论 7 2
  • 今天文章的灵感来自最新特工题材美剧《柏林谍影》第一季第一集。 我个人认为这部美剧拍得很棒,是我观看特工题材美剧至今...
    李安迪阅读 475评论 2 16
  • 转瞬时间过去了三个月,之前的计划有的坚持的好,有的没有按计划完成。此刻,坐在电脑前,我试着问自己:过去的三个月,我...
    阿禾e阅读 66评论 19 15
  • 很久以来,一直有个问题,想不明白,看不明白,为什么有的人能够自然而然的散发着很强的磁场,很有高贵的气质,一种天...