一、利用 RAC 实现代理
前提:自定义一个 UIView: XMView, 里面有一个 UISwitch: colorSwitch 控件,并将 XMView 添加到控制器:ViewController中;
需求:通过改变 colorSwitch 控件的开关来改变控制器的背景色
实现方式一:利用 RACSubject 实现代理
1、在 XMView 中定义一个公开属性:delegateSignal
@property (nonatomic, strong) RACSubject *delegateSignal;
2、在 XMView 中实现colorSwitch 控件的事件,并在实现中,发送信号
- (IBAction)switchDidTap:(UISwitch *)sender {
// 判断代理信号是否有值
if (self.delegateSignal) {
// 有值,才需要发送 UISwitch 的状态
[self.delegateSignal sendNext:sender.isOn];
}
}
3、在 控制器:ViewController中初始化XMView
- (void)viewDidLoad {
[super viewDidLoad];
// 初始化 XMView
XMView *delegeteView = [[XMView alloc] init];
[self.view addSubview:delegeteView];
// 设置代理信号
delegeteView.delegateSignal = [RACSubject subject];
// 订阅代理信号, 监听 Switch 状态的改变
[delegeteView.delegateSignal subscribeNext:^(BOOL x) {
self.view.backgroundColor = x ? [UIColor whiteColor] : [UIColor blackColor];
}];
}
实现方式二:利用 rac_signalForSelector: 实现代理
1、在 XMView 中实现colorSwitch 控件的事件,并且空实现(只定义方法)
- (IBAction)switchDidTap:(UISwitch *)sender {
}
2、在 XMView 中定义一个公开方法,和colorSwitch 控件的事件方法名相同
- (IBAction)switchDidTap:(UISwitch *)sender;
3、在 控制器:ViewController中初始化XMView
- (void)viewDidLoad {
[super viewDidLoad];
// 初始化 XMView
XMView *delegeteView = [[XMView alloc] init];
[self.view addSubview:delegeteView];
// 订阅代理信号, 监听 Switch 状态的改变
[[delegeteView rac_signalForSelector:@selector(switchDidTap:)] subscribeNext:^(RACTuple * _Nullable x) {
UISwitch *switch = (UISwitch *)x[0];
self.view.backgroundColor = switch.isOn ? [UIColor whiteColor] : [UIColor blackColor];
}];
}
二、RACCommand 简介和使用
RACCommand: RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程
使用场景:监听按钮点击,网络请求
一、RACCommand使用步骤:
- 1.创建命令
initWithSignalBlock:(RACSignal*(^)(id input))signalBlock
- 2.在
signalBlock
中,创建RACSignal
,并且作为signalBlock
的返回值 - 3.订阅
RACCommand
中的信号,获取数据 - 4.执行命令
- (RACSignal *)execute:(id)input
// 1.创建命令
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
// 2.创建信号,用来传递数据
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
// 模拟网络加载
[self loadData:^(id response) {
// 注意:数据传递完,最好调用sendCompleted,这时命令才执行完毕。
[subscriber sendNext:response];
[subscriber sendCompleted];
} fail:^(NSError *error) {
[subscriber sendError:error];
}];
return nil;
}];
}];
// 3.订阅RACCommand中的信号
[command.executionSignals subscribeNext:^(id _Nullable x) {
// x 为信号中的信号
[x subscribeNext:^(id _Nullable x) {
// 此处的 x 才是网络请求到的数据
NSLog(@"%@",x);
}];
}];
// 4.执行命令, 执行时可以传值
[command execute:nil];
其中上述步骤三可以简化
// switchToLatest:用于signal of signals,获取signal of signals发出的最新信号,也就是可以直接拿到RACCommand中的信号
[command.executionSignals.switchToLatest subscribeNext:^(id x) {
// 网络请求到的数据
NSLog(@"%@",x);
}];