APIWrappers是简单介绍API使用的,就不会讲了,可以说看一遍就好了,这种东西,熟能生巧别无他法。
Calculator 相信是每个初学者都做过的项目。回想当初一坨不忍直视的代码,相信你看到RxSwift的样例会觉得,还有这样简洁的计算器!实在惭愧,入行几年我自认为写不出这样的分级,每天工作都被业务代码填充。几乎没有多少时间自己琢磨精妙的代码,时常会感觉到了瓶颈,希望能借这一系列博客学到大牛编码的思想。与君共勉。
Calculator.swift 里面定义了大量的enum来判断当前的状态。符号,命令,状态。
一句一句读就好理解了,
let system = Observable.system(
CalculatorState.initial,
accumulator: CalculatorState.reduce,
scheduler: MainScheduler.instance,
feedback: { _ in commands }
)
// .debug("calculator state")
.shareReplayLatestWhileConnected()
这里有一个公用方法来绑定了MainScheduler.instance。
allClearButton.rx.tap.map { _ in .clear }
像这样点击allClearButton就会触发CalculatorState变化,
case .clear:
return CalculatorState.initial
结果就是重新实例化一个CalculatorState。自然默认就是0.
理解这一个按钮点击的变化事件,其他的按钮都是一样的。
func mapScreen(transform: (String) -> String) -> CalculatorState {
switch self {
case let .oneOperand(operand, screen):
return .oneOperand(operand: operand, screen: transform(screen))
case let .oneOperandAndOperator(operand, operat, screen):
return .oneOperandAndOperator(operand: operand, operator: operat, screen: transform(screen))
}
}
显示屏幕也做的很巧妙。分为需要显示符号和不需要显示符号两个case。有一个问题我一直没搞清的是CalculatorState.reduce是在什么时候改变的呢,我以为是在写符号的时候,因为点击运算符号也就意味着需要显示符号会为true,但代码看来并不是。
答案在这个方法里面static func reduce(state: CalculatorState, _ x: CalculatorCommand) -> CalculatorState
但是外面并没有传值进入这个方法,那么states又是怎么来的呢。大家思考一分钟。
其实有这个想法的都进入了一个误区,states根本不是外来的,而是自身的。CalculatorState 本身就是一个enum,当然有俩个states了。在第二个延展里面,清楚的记录了
case .operation(let o):
switch state {
case let .oneOperand(_, screen):
return .oneOperandAndOperator(operand: Double(screen) ?? 0.0, operator: o, screen: "0")
case let .oneOperandAndOperator(operand, o, screen):
return .oneOperandAndOperator(operand: o.perform(operand, Double(screen) ?? 0.0), operator: o, screen: "0")
}
case .equal:
switch state {
case let .oneOperandAndOperator(lhs, o, screen):
let result = o.perform(lhs, Double(screen) ?? 0.0)
return .oneOperand(operand: result, screen: String(result))
如果是点击符号,初始的oneOperand状态,会变成oneOperandAndOperator,而点击等于好,oneOperandAndOperator会变成oneOperand。哈,就像BOOL一样,只会有一个值出现。goodNews,除此之外,应该没有什么难点了。