1、特點:
在事件發生的時候立刻做出反應。
2、以下操作都是響應式編程:
Target
Delegate
KVO
通知
時鐘
網絡異步回調
3、目的:
接管事件的監聽
4、注意(坑):
(1)RAC最大的坑是循環引用
(2)多人開發中,確保所有人的代碼風格一致
(3)個人開發,要注意版本對應的語言:
2.5以下全都是OC,
3.0是OC末代,
4.0開始swift2.0
5.0開始支持swift3.0
6.0開始支持swift4.1 等等,
具體看github的介紹吧。
初識
//RACSignal 信號
/*
創建信號
訂閱信號
發送信號
*/
//創建
RACSignal *sigal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
NSLog(@"創建了信號");
//發送
[subscriber sendNext:@"this is RAC"];
NSLog(@"發送了信號");
return nil;
}];
//訂閱
[sigal subscribeNext:^(id _Nullable x) {
//x 信號的內容
NSLog(@"%@",x);
NSLog(@"訂閱了信號");
}];
/*
2017-10-10 15:14:25.875726+0800 RAC[23884:952541] 創建了信號
2017-10-10 15:14:25.875982+0800 RAC[23884:952541] this is RAC
2017-10-10 15:14:25.876127+0800 RAC[23884:952541] 訂閱了信號
2017-10-10 15:14:25.876640+0800 RAC[23884:952541] 發送了信號
*/
/*
創建信號必須先訂閱
訂閱信號必須先發送
*/
KVO
[RACObserve(self.person, name) subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
Target
[[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
// x is btn
NSLog(@"%@",x);
}];
Delegate
[[self.field rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"%@",x);
}];
通知
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"qwe" object:nil] subscribeNext:^(NSNotification * _Nullable x) {
NSLog(@"%@",x);
}];
組合 (登錄爲例)
//x is 0 or 1
// so
RAC(self.btn,enabled) =
[[RACSignal combineLatest:@[self.field.rac_textSignal,self.field2.rac_textSignal]] reduceEach:^id _Nullable(NSString *account ,NSString *pwd){
return @(account.length && account.length);
}];
//命令
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
NSLog(@"密碼加密");
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"請求登錄"];
[subscriber sendCompleted]; //發出命令完成
return nil;
}];
}];
//命令執行的過程
[[command.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
if ([x boolValue]) {
NSLog(@"顯示等待....");
}else{
NSLog(@"移動等待");
}
}];
//拿到最新的信號
[command.executionSignals.switchToLatest subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
[[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
//執行命令
[command execute:nil];
}];
MVVM架構下優化組合信號
#import <Foundation/Foundation.h>
#import "ReactiveObjC.h"
@interface LoginViewModel : NSObject
@property (nonatomic,strong) RACSignal *loginBtnEnableSignal;
@property (nonatomic,strong) RACCommand *loginCommand;
@property (nonatomic,strong) NSString *account;
@property (nonatomic,strong) NSString *pwd;
@end
//
// LoginViewModel.m
// RAC
//
// Created by WiKi on 2017/10/18.
// Copyright © 2017年 wiki. All rights reserved.
//
#import "LoginViewModel.h"
@implementation LoginViewModel
- (instancetype)init{
self =[super init];
if (self) {
[self setUp];
}
return self;
}
- (void)setUp{
_loginBtnEnableSignal =
[[RACSignal combineLatest:@[RACObserve(self, account),RACObserve(self, pwd)]] reduceEach:^id _Nullable(NSString *account ,NSString *pwd){
return @(account.length && account.length);
}];
//command
//命令
self.loginCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
NSLog(@"密碼加密");
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"請求登錄"];
[subscriber sendCompleted]; //發出命令完成
return nil;
}];
}];
//命令執行的過程
[[self.loginCommand.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
if ([x boolValue]) {
NSLog(@"顯示等待....");
}else{
NSLog(@"移動等待");
}
}];
//拿到最新的信號
[self.loginCommand.executionSignals.switchToLatest subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
}
@end
RAC(self.loginViewModel,account) = self.field.rac_textSignal;
RAC(self.loginViewModel,pwd) = self.field2.rac_textSignal;
RAC(_btn,enabled) = self.loginViewModel.loginBtnEnableSignal;
[[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
//執行命令
[_loginViewModel.loginCommand execute:nil];
}];