RAC 響應式編程

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];

    }];
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章