在开始学习 RxSwift 以前,必定要对 Swift 相关语法有所了解,不然就很难理解为何能够这样。关于 Swift 的学习其实只要看看 Swift 的官方文档就可够了。我以前也列过一些学习资源:来自一线开发者的Swift学习资源推荐。
如今开始进入正题。编程
想一个有趣的问题,为何没有 RxObjc 呢?
实际上响应式的编程框架对语言仍是有些要求的,固然 OC 确实也有一个奠定式的 FRP 框架 ReactiveCocoa。可是客观的说,在 Swift 里响应式的框架写起来会愉快的多,或者说更能发挥出语言的优点。
Swift 契合响应式有如下几点:swift
Swift 中的枚举(Enum)能力相比 OC 能够说获得了升华。再也不只是一个相似预编译时的宏,而是一个完整的类型。和 Struct 同样,能够给他定义初始化方法,声明函数,添加扩展。一样的泛型一样也试用于 Enum。
枚举还有一项神奇的能力叫关联值。一个枚举能够的值能够是不一样的类型。官方手册里的示例代码以下:闭包
enum ServerResponse { case result(String, String) case failure(String) } let success = ServerResponse.result("6:00 am", "8:09 pm") let failure = ServerResponse.failure("Out of cheese.") switch success { case let .result(sunrise, sunset): print("Sunrise is at \(sunrise) and sunset is at \(sunset).") case let .failure(message): print("Failure... \(message)") }
每一个 case 能够携带不一样的类型,而且能够不止是一个值。
当 Enum 结合泛型,就发生了有趣的事。直接贴代码:并发
enum OptionalValue<Wrapped> { case none case some(Wrapped) } var possibleInteger: OptionalValue<Int> = .none possibleInteger = .some(100)
这就是 Swift 中的 Optional 实现的相似代码。使用枚举实现,表示值有两种可能:没有值的 .none 和是 Wrapped 类型的 .some。
有了以上的知识咱们再来看 Rx 中的事件流中的值Event
:app
public enum Event<Element> { /// Next element is produced. case next(Element) /// Sequence terminated with an error. case error(Swift.Error) /// Sequence completed successfully. case completed }
每一次事件的值有三种可能:1.值(next),2.完成结束(completed),3.失败(error)。框架
若是函数在声明时设置了一个默认值,那么在调用时这个参数就能够不传。
假设咱们给 Int 定义个扩展方法increment
。若是不传入值则默认加1,若是传入就按照传入的值增长:函数
extension Int { func increment(with number: Int = 1) -> Int { return self + number } }
使用的时候 Xcode 就会提示两个函数:
再也不须要像 OC 同样定义几个函数。
Rx 表示订阅的subscribe
函数,有时只要写onNext
,有时只要写onError
,就是由于这个函数在声明时同时指定了默认参数:学习
extension ObservableType { public func subscribe(file: String = #file,line: UInt = #line, function: String = #function, onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)-> Disposable { // ... }
能够看到这个函数为订阅每一个事件可能都声明了默认参数,因此你在订阅时能够只订阅本身关注的订阅。优化
闭包的使用相似 OC 中的 block,具体使用就再也不介绍。提一下新手很容易忽略的语法糖。spa
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 }) s1 和 s2 的类型和返回值类型 Xcode 能够推断出来能够省略: reversedNames = names.sorted(by: { (s1, s2) in return s1 > s2 })
return
reversedNames = names.sorted(by: { (s1, s2) in s1 > s2 })
reversedNames = names.sorted(by: { $0 > $1 })
reversedNames = names.sorted(by: >)
当参数的最好一个参数是闭包时,能够直接把最后一个闭包的实现跟在函数后面。
直接贴代码表示:
// 一个最后一个参数是闭包的函数 func someFunctionThatTakesAClosure(closure: () -> Void) { // function body goes here } // 默认的调用方法 someFunctionThatTakesAClosure(closure: { // closure's body goes here }) // 省略最后一个参数的方法名,而且把闭包的实现直接跟在函数后面 someFunctionThatTakesAClosure() { // trailing closure's body goes here } 这种写法简化了代码,让代码看起来更简洁。 Rx 中的数据流操做符能够灵活的组织闭包,常常会用到简化的闭包的语法。 Observable.of(1, 2, 3, 4, 5, 6) .filter { $0 % 2 == 0} .subscribe(onNext: { print($0) })
刚开始的时候可能有点看不明白,慢慢的还原闭包的语法,以后看多了就会熟悉的。