响应式编程已经出了很完整的框架了
比如ReactiveCocoa 简称RAC,前段时间有个项目是这个框架(感觉贼鸡儿晦涩难懂,完全把编程思路要整个转换,如果之前不是用这个编程范式),ReactiveCocoa是专门针对的OC Swift,换句话说暂时来说是适配苹果各平台开发(iOS,Mac)
再比如ReactiveX,这个这个版本支持的语言就更多了,也不是很重要,就不细较了,唯一值得在意的是RXSwift
use_frameworks!
target 'UItest' do
pod 'RxSwift','~>5'
pod 'RxCocoa','~>5'
end
然后pod install完成第三方库安装,这里是用的cocoapods的方式,安装好了说说
使用教程:
1.导入
import RxSwift //不包括iOS的任何特性
import RxCocoa //包含iOS UI等一些东西
2.响应式编程的重要角色
Obsevable : 负责发送事件(event)
Observer: 负责订阅Obsevable,监听Obsevable发送的事件(我觉得这里应该叫事件队列,因为很可能是一串数据)
这个过程有点类似于KVO,过程中重要的是事件
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
}
RxSwift官方定义事件是个枚举,如上图,有三个case,可见事件是有三个状态,1.next携带了具体数据,x携带的是个Element,这是个泛型,也就是数据类型不定。2.error,是一个错误信息,具体传出的是Swift.Error ,整个过程会终止。3.completed 这个完成是队列完成的意思,表示这一个监听过程整个完成了,并没有出错
所以可以确定正常的事件,传递的是next,因为2,3显然说明事件异常终止,或者顺利完成
3.基本运用
enum MYError:Error {case test }
let observable = Observable<Int>.create { observer in //创建个 observable
observer.onNext(1) //发送事件
observer.onNext(2)
observer.onNext(3)
observer.onError(MYError.test)
observer.onCompleted()
observer.onNext(4)
return Disposables.create()
}
observable.subscribe { event in //注册监听
switch event
{
case .next(let content):
print(content)
case .error(let error):
print(error)
case .completed:
print("完成")
}
}
上述就是RX的基本运用,实战里面发消息和接消息的一般在两个不同的类,从打印的log也可以看出,不管是onError还是onCompleted(代码位置有限就没单独展示区别),之后就会结束这个响应过程
observable.subscribe { content in
print(content)
} onError: { error in
print(error)
} onCompleted: {
print("完成")
} onDisposed: {
print("注销")
}
监听还有一种方式,区别不是很大,但会多一个注销,注销和完成是类似的,区别在于,注销是由监听者结束这个响应流程,而Completed是由消息发送者结束
let disp = observable.subscribe { event in //注册监听
switch event
{
case .next(let content):
print(content)
case .error(let error):
print(error)
case .completed:
print("完成")
}
}
disp.dispose()
这是注册监听的返回值,所以注销的权限是由监听持有(虽然我这里写在了一个函数里,实际实战监听和发送者肯定不在一起)
let observable = Observable.just(1)
let disp = observable.subscribe { content in
print(content)
} onError: { error in
print(error)
} onCompleted: {
print("完成")
} onDisposed: {
print("注销")
}
disp.dispose()
如果不是需要经常发送,也有单次发送
4.UI层面的运用
程序常需要一些计时器之类的东西,比如登录注册页面的短信倒计时,这事解决办法挺多了,说下RX的解决方式
let observable = Observable<Int>.timer(.seconds(2), period: .seconds(1), scheduler: MainScheduler.instance)
observable.map{"\($0)"}.bind(to: label.rx.text)
需要很复杂的操作,也可以用subscribe函数进行高度自定义,这里就只是展示计时器和bind函数,timer还能用的是两个函数,一个不需要延时,这个是高度定制的可延时函数,
后面的bind是必须用rx的,这个rx的详细参见前面的协议编程,里面做过特殊处理的,这里不是直接传入label.text就可以的
然后UI层面最重要的我感觉就是Binder
let label = UILabel.init(frame: CGRect(x: 0, y: 50, width: UIScreen.main.bounds.width, height: 25))
self.view.addSubview(label)
let binder = Binder<Int>(label, binding: { label, v in
label.text = "剩余" + "\(160 - v)"
})
let _ = Observable<Int>.timer(.seconds(2), period: .seconds(1), scheduler: MainScheduler.instance).subscribe(binder)
具体用法参照代码