初识 RAC

一.RAC 是什么?能做什么?

1.RAC是Reactive Cocoa的简称,是一种支持函数式响应式编程的框架,由GitHub团队编写而成。

2.RAC可以做什么呢?
RAC通过信号的方式,链接组合和反应。通过一个统一的方法来处理异步行为,包括通知(NotificationCenter)、委托代理(Delegate)、目标操作机制(AddTarget)、KVO、回调Block。
也就是通过block的方式,来处理和简化这些异步行为。

3.版本大事件:
2.5以及之前版本不支持swift。
3.0版本ReactiveObjC是支持OC的最后一个版本。
4.0版本ReactiveSwift开始只支持swift。

二.为什么用RAC? 优缺点!

喜欢一个人,往往是从他身上的某个闪光点开始。

1.RAC有哪些闪光点?[需要进一步了解]
a.简洁高效,一行代码能解决的问题就不要用多行了(就不能写半行)
b.注册的通知,不需要释放,RAC内部帮你做了。

2.缺点
a.高耦合性
b.需要进一步了解


三.怎么使用ARC?

1.使用pod方式进行安装,GiTHub团队已经将支持OC和swift的支持库分开了,使用OC的可以

pod 'ReactiveObjC', '~> 3.0.0'

2.引入头文件

#import 

3.开始进入正题。
RAC是通过信号方式,链接组合和反应。所以要有三步,创建信号、监听信号、发送信号、(订阅信号)。
RAC发送信号包括了三种情况,下一步该做什么、成功之后做什么、失败(出错)之后该做什么。


初识 RAC_第1张图片
3E9F1542F5CB44B234EE93713D1F58A6.jpg
    // 创建信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
    
        // 发送信号,有三种情况,下一步,出错、失败
        [subscriber sendNext:@"RAC 我来了!"];
        [subscriber sendError:nil];
        [subscriber sendCompleted];
 
        return nil;
    }];
    
    // 订阅信号 (也可以分开写)
    [signal subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"%@",x);

    } error:^(NSError * _Nullable error) {
        
        NSLog(@"%@",error);

    } completed:^{
        
        NSLog(@"RAC 成功到达地球");
    }];

// ----------------也可以简化写法-----------------------
    // 创建信号
    [[RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        
        // 发送信号
        [subscriber sendNext:@"RAC 我来了!"];
        
        return nil;
    }] subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"%@",x);
    }];

4.避免循环引用,在block内部用self来引用控制器的成员变量, 可能会造成循环引用,这个时候在“外部用@weakify,内部用@strongify”这个方式来解决,如果直接用“_”来引用成员变量,可能会解决不了循环引用的问题

    //问题:在信号中打印了控制器,也就是强引用了控制器,控制器中又强引用了信号,如下,就会形成循环应用
    //信号外部用@weakify,内部用@strongify
    @weakify(self)
    
   RACSignal *signal = [[btn rac_signalForControlEvents:UIControlEventTouchUpInside]subscr subscribeNext:^(__kindof UIControl * _Nullable x) {
        
        @strongify(self);
       self.lable.text = @"这是来自RAC的信号!!!";
       
    }];
    
    self.signal = signal;

4.RAC中实现KVO
可以通过宏RACObserve来实现,绝壁一行代码,替代addObserver: forKeyPath:options: context:(void *)context

RAC中强大的宏,拿来小用一下Observe
#define RACObserve(TARGET, KEYPATH) _RACObserve(TARGET, KEYPATH)
  
    // 当对象self.dog的属性nickName发生变化时,就会调用这个block
    [RACObserve(self.dog, nickName) subscribeNext:^(id  _Nullable x) {
        self.label.text = x;  // x是subScribe发送的内容
    }];

5.RAC中实现控件的事件(addTarget)
查看源码可以看到,其实RAC写了一个UIControl的分类 "UIControl+RACSignalSupport.h",在分类中完成了信号的三部曲,创建信号、订阅信号、发布信号。

    [[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        
        NSLog(@"使用RAC添加按钮事件!!!");
    }];

6.RAC中有关控件,比较好玩的地方,真心推荐应该玩一下。
想用什么控件,就去RAC包中去找相关的扩展就好了,不多说,代码走起。。。比如监听UITextField的输入


初识 RAC_第2张图片
图片.png

// 传统方式监听UITextField的输入,需要很多代码,这里不多说,
// 使用ARC是怎么玩起来的呢?好吧,开始你的表演!别忘去哪里找?
// 去RAC包中有关UITextField的扩展,你会发现这个扩展其实都叫做
// RACSignalSupport

    [[self.textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
       
        NSLog(@"textField==>text ==>%@",x);
    }];

7.同时获取多个控件的变化,在RAC中就是将多个信号合并成一个信号进行处理,使用+ (RACSignal *)combineLatest:(id)signals
so easy!最好不要超过5个(因为限制了呢,证据在下面代码里)。

    [[RACSignal combineLatest:@[self.textField.rac_textSignal,self.textField2.rac_textSignal]] subscribeNext:^(RACTuple * _Nullable x) {
      
        NSString *name = x.first;
        NSString *pwd = x.second;
        
        NSLog(@"name===>%@,pwd===>%@",name,pwd);
    }];


// --------------限制个数的证据在此--------------
typedef struct {
    unsigned long state;
    id __unsafe_unretained _Nullable * _Nullable itemsPtr;
    unsigned long * _Nullable mutationsPtr;
    unsigned long extra[5];
} NSFastEnumerationState;

// --------------限制个数的证据在此--------------

8.巧妙使用reduce,合并信号的数据,进行统计计算使用,例如判断手机号和密码同时存在,才可以点击登录按钮

    [[RACSignal combineLatest:@[nameTextField.rac_textSignal, pwdTextField.rac_textSignal] reduce:^id _Nullable(NSString * name, NSString * pwd){
        
        NSLog(@"%@ ,%@", name,pwd);
        
        return @(name.length > 0 && pwd.length > 0);
        
        return nil;
        
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
        
        _demoButton.enabled = [x boolValue];
    }];






备注: 如果pod安装,遇到一下错误
图片.png

解决方法:在pod 'ReactiveCocoa’,’~>3.0’前面添加use_frameworks!

use_frameworks!
pod 'ReactiveCocoa’,’~>3.0’

原因:对于 Swift 项目,CocoaPods 提供了动态 Framework 的支持。通过 use_frameworks! 选项控制。对于 Swift 写的库来说,想通过 CocoaPods 引入工程,必须加入 use_frameworks! 选项。

你可能感兴趣的:(初识 RAC)