详解如何使用ReactiveObjC

概述

RAC架构框架图

信号流程

基本使用

1、基本控件

UITextField

//监听文本输入
 [[_textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"%@",x);
 }];

//可根据自己想要监听的事件选择
 [[_textField rac_signalForControlEvents:UIControlEventEditingChanged] subscribeNext:^(__kindof UIControl * _Nullable x) {
     NSLog(@"%@",x);
 }];
//添加条件 -- 下面表示输入文字长度 > 10 时才会调用subscribeNext
 [[_textField.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
     return value.length > 10;
 }] subscribeNext:^(NSString * _Nullable x) {
     NSLog(@"输入框内容:%@", x); }];

UIButton

//监听按钮点击事件
[[_btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"-->%@",x);
}];

计时器(interval、delay)

//类似timer
@weakify(self)
self.disposable = [[RACSignal interval:2 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {
        @strongify(self)
        NSLog(@"时间:%@", x); // x 是当前的时间
        //关闭计时器
        [self.disposable dispose];
}];
//延时
[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@"延时2秒"];
        return nil;<br>}] delay:2] subscribeNext:^(id x) {

        NSLog(@"-->%@",x);
}];

2、监听属性变化

//监听self的name属性
[RACObserve(self, name) subscribeNext:^(id  _Nullable x) {
        NSLog(@"属性的改变-->%@",x);
}];
[[self rac_valuesForKeyPath:@"name" observer:self] subscribeNext:^(id  _Nullable x) {
        NSLog(@"属性的改变-->%@", x);
}];
//此处RAC宏相当于让_label订阅了_textField的文本变化信号
//赋值给label的text属性
RAC(_label, text) = _textField.rac_textSignal;

3、遍历数组和字典

//遍历数组
 NSArray *array = @[@"1", @"2", @"3", @"4", @"5"];
[array.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
      NSLog(@"内容-->%@", x)<br>}];

4、监听 Notification 通知事件

[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"notification" object:nil] subscribeNext:^(NSNotification * _Nullable x) {
        NSLog(@"-->%@", x);
}];

5、代替Delegate代理

//监听按钮点击方法的信号
//当执行完btnClickAction后会执行此订阅
[[self rac_signalForSelector:@selector(btnClickAction:)] subscribeNext:^(RACTuple * _Nullable x) {
        NSLog(@"-->%@", x);
}];
-(void) btnClickAction:(UIButton *)btn
{
    NSLog(@"按钮点击");
}

二、RAC常用类

RACSignal

RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
      [subscriber sendNext:@"🍺🍺🍺🍺🍺🍺🍺"];
      [subscriber sendCompleted];
      return [RACDisposable disposableWithBlock:^{
          NSLog(@"销毁了🍺🍺🍺");
      }];
  }];
  [signal subscribeNext:^(id  _Nullable x) {
      NSLog(@"%@",x);
  }];

RACSubject(可发送信号也可以订阅信号)

RACTuple(元组)-- 其内部就是封装了数组,用起来跟数组差不多

//通过定值创建RACTuple
RACTuple *tuple = [RACTuple tupleWithObjects:@"1", @"2", @"3", nil];
//利用 RAC 宏快速封装
RACTuple *tuple2 = RACTuplePack(@"1", @"2", @"3");
//从别的数组中获取内容
RACTuple *tuple3 = [RACTuple tupleWithObjectsFromArray:@[@"1", @"2", @"3"]];

NSLog(@"元组-->%@", tuple3[0]);
NSLog(@"第一个元素-->%@", [tuple3 first]);
NSLog(@"最后一个元素-->%@", [tuple3 last]);

RACMulticastConnection -- 用于当一个信号,被多次订阅时,为了保证创建信号时,避免多次调用创建信号中的block

RACSignal *signal1 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
       [subscriber sendNext:@"signal1-->🍺🍺🍺🍺🍺🍺🍺"];
       [subscriber sendCompleted];
       return [RACDisposable disposableWithBlock:^{
           NSLog(@"signal1销毁了");
       }];
   }];

   RACMulticastConnection *connection = [signal1 publish];

   [connection.signal subscribeNext:^(id  _Nullable x) {
       NSLog(@"subscribeNext-->1");
   }];
   [connection.signal subscribeNext:^(id  _Nullable x) {
       NSLog(@"subscribeNext-->2");
   }];
   [connection.signal subscribeNext:^(id  _Nullable x) {
       NSLog(@"subscribeNext-->3");
   }];
   [connection connect];

RACCommand -- 可以监听信号的状态等

NSString *input = @"执行";
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
    NSLog(@"input-->%@",input);
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [subscriber sendNext:@"🍺🍺🍺🍺🍺🍺🍺"];
        [subscriber sendError:[NSError errorWithDomain:@"error" code:-1 userInfo:nil]];
//            [subscriber sendCompleted];
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"signal销毁了");
        }];
    }];
}];
[command.executionSignals subscribeNext:^(RACSignal   * _Nullable x) {
    NSLog(@"executionSignals-->%@",x);
    [x subscribeNext:^(id  _Nullable x) {
        NSLog(@"executionSignals-->subscribeNext-->%@",x);
    }];
}];
[[command.executionSignals switchToLatest] subscribeNext:^(id  _Nullable x) {
    NSLog(@"switchToLatest-->%@",x);
}];
[command.executing subscribeNext:^(id  _Nullable x) {
    NSLog(@"executing-->%@",x);
}];
[command.errors subscribeNext:^(id  _Nullable x) {
    NSLog(@"errors-->%@",x);
}];
//开始执行
[command execute:input];

三、高级函数使用

1、连接信号、合并信号等

首先创建两个信号signal1和signal2来演示

RACSignal *signal1 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
     [subscriber sendNext:@"signal1-->🍺🍺🍺🍺🍺🍺🍺"];
     [subscriber sendCompleted];
     return [RACDisposable disposableWithBlock:^{
         NSLog(@"signal1销毁了");
     }];
 }];
 RACSignal *signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
     [subscriber sendNext:@"signal2-->🍺🍺🍺🍺🍺🍺🍺"];
     [subscriber sendCompleted];
     return [RACDisposable disposableWithBlock:^{
         NSLog(@"signal2销毁了");
     }];
 }];

1.1、 concat -- 当多个信号发出的时候,有顺序的接收信号

一个信号signal3去监听signal1和signal2,必须是接收signal1完后才会接收signal2

RACSignal *signal3 = [signal1 concat:signal2];
  [signal3 subscribeNext:^(id  _Nullable x) {
      NSLog(@"signal3-->%@",x);
  }];

1.2、 combineLatestWith -- 将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的signal至少都有过一次sendNext,才会触发合并的信号(订阅者每次接收的参数都是所有信号的最新值),不论触发哪个信号都会触发合并的信号

一个信号signal3去监听signal1和signal2,每次回调两个信号的最新值

RACSignal *signal3 = [signal1 combineLatestWith:signal2];
   [signal3 subscribeNext:^(id  _Nullable x) {
       NSLog(@"%@",x);
   }];

PS:注释signal1的sendNext方法,直接销毁了,所以每个singal必须有sendNext方法

1.3、 then -- 用于连接两个信号,等待第一个信号完成,才会连接then返回的信号

RACSignal *signal3 = [signal1 then:^RACSignal * _Nonnull{
    return signal2;
}];
[signal3 subscribeNext:^(id  _Nullable x) {
    NSLog(@"signal3-->%@",x);
}];

1.4、 merge -- 把多个信号合并为一个信号来监听,任何一个信号有新值的时候就会调用

一个信号signal3去监听signal1和signal2,每次回调一个信号

RACSignal *signal3 = [signal1 merge:signal2];
[signal3 subscribeNext:^(id  _Nullable x) {
    NSLog(@"signal3-->%@",x);
}];

1.5、 zipWith -- 把两个信号压缩成一个信号,只有当两个信号都发出信号内容时,才会触发

一个信号signal3去监听signal1和signal2,但必须两个信号都有发出(不需要同时,例如signal1信号发出了,signal2信号等了10秒之后发出,那么signal3的订阅回调是等signal2信号发出的那一刻触发)

RACSignal *signal3 = [signal1 zipWith:signal2];
[signal3 subscribeNext:^(id  _Nullable x) {
    NSLog(@"signal3-->%@",x);
}];

1.6、 reduce 聚合 -- 把多个信号的值按照自定义的组合返回

RACSignal *signal3 = [RACSignal combineLatest:@[signal1,signal2] reduce:^id(NSString *s1 ,NSString *s2){
    return [NSString stringWithFormat:@"%@ %@",s1,s2];
}];
[signal3 subscribeNext:^(id x) {
    NSLog(@"%@",x);
}];

2、flattenMap & map 映射

flattenMap 的底层实现是通过bind实现的

map 的底层实现是通过 flattenMap 实现的

//map事例
[[_textField.rac_textSignal map:^id _Nullable(NSString * _Nullable value) {
        return [NSString stringWithFormat:@"%@🍺🍺🍺🍺🍺🍺🍺",value];
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"-->%@",x);
    }] ;
//flattenMap事例
 [[_textField.rac_textSignal flattenMap:^__kindof RACSignal * _Nullable(NSString * _Nullable value) {
        return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            [subscriber sendNext:[NSString stringWithFormat:@"%@🍺🍺🍺🍺🍺🍺🍺",value]];
            [subscriber sendCompleted];
            return [RACDisposable disposableWithBlock:^(){}];
        }];
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"-->%@",x);
    }] ;

3、filter -- 过滤、ignore -- 忽略、distinctUntilChanged -- 忽略相同

filter、ignore

//map事例
[[_textField.rac_textSignal map:^id _Nullable(NSString * _Nullable value) {
        return [NSString stringWithFormat:@"%@🍺🍺🍺🍺🍺🍺🍺",value];
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"-->%@",x);
    }] ;
//flattenMap事例
 [[_textField.rac_textSignal flattenMap:^__kindof RACSignal * _Nullable(NSString * _Nullable value) {
        return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            [subscriber sendNext:[NSString stringWithFormat:@"%@🍺🍺🍺🍺🍺🍺🍺",value]];
            [subscriber sendCompleted];
            return [RACDisposable disposableWithBlock:^(){}];
        }];
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"-->%@",x);
    }] ;

distinctUntilChanged

RACSubject *subject = [RACSubject subject];
   [[subject distinctUntilChanged] subscribeNext:^(id  _Nullable x) {
       NSLog(@"-->%@",x);
   }];
   [subject sendNext:@"123"];
   [subject sendNext:@"123"];
   [subject sendNext:@"123"];
   [subject sendNext:@"🍺🍺🍺🍺🍺🍺"];
   [subject sendNext:@"🍺🍺🍺🍺🍺🍺"];
   [subject sendCompleted];

以上就是详解如何使用ReactiveObjC的详细内容,更多关于如何使用ReactiveObjC的资料请关注我们其它相关文章!

时间: 2021-06-05

如何在IOS中使用Cordova插件

一.准备 插件功能:打开IOS相机 1:创建插件 plugman create --name [插件名称] --plugin_id [插件ID] --plugin_version [插件版本号] plugman create --name CameraDemo --plugin_id cordova-plugin-camerademo --plugin_version 1.0.0 2:添加IOS平台 plugman platform add --platform_name ios 3:创建pac

iOS实现循环滚动公告栏

本文实例为大家分享了iOS实现循环滚动公告栏的具体代码,供大家参考,具体内容如下 封装了一个继承于UIView的类,如下: #import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @interface XtayNoticeScrollView : UIView - (instancetype)initWithFrame:(CGRect)frame titleArray:(NSArray<NSString *> *)titleArray; -

详解IOS判断当前网络状态的三种方法

在项目中,为了好的用户体验,有些场景必须线判断网络状态,然后才能决定该干嘛.比如视频播放,需要线判断是Wifi还是4G,Wifi直接播放,4G先提示用户.获取网络状态的方法大概有三种: 1. Reachability 这是苹果的官方演示demo中使用到的方法,我们可以到苹果官方文档里下载Demo(点击左上角Download Sample Code 即可下载),然后把Demo里的Reachability.h和.m考到自己项目中,并在Build Phases 的 Link Binary 添加Syst

iOS UIBezierPath实现饼状图

本文实例为大家分享了iOS UIBezierPath实现饼状图的具体代码,供大家参考,具体内容如下 首先看效果图: 代码: #import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @interface CircleView : UIView @property (nonatomic, copy) NSArray<NSNumber *> *valueArray; @end NS_ASSUME_NONNULL_END // #define S_W

如何在IOS中使用IBeacon

什么是iBeacon? iBeacon 是苹果公司2013年9月发布的移动设备用OS(iOS7)上配备的新功能.其工作方式是,配备有低功耗蓝牙(BLE)通信功能的设备使用BLE技术向周围发送自己特有的 ID,接收到该 ID 的应用软件会根据该 ID 采取一些行动. 从个人的角度看: iBeacon向四面八方不停地广播信号,就像是往平静的水面上扔了一块石子,泛起层层涟漪(俗称水波),波峰相当于 iBeacon 的RSSI(接受信号强度指示),越靠近中心点的地方波峰越高(RSSI 越大),这个波峰的

详解 iOS 系统中的视图动画

动画为用户界面的状态转换提供了流畅的可视化效果, 在 iOS 中大量使用了动画效果, 包括改变视图位置. 大小. 从可视化树中删除视图, 隐藏视图等. 你可以考虑用动画效果给用户提供反馈或者用来实现有趣的特效. 在 iOS 系统中, Core Animation 提供了内置的动画支持, 创建动画不需要任何绘图的代码, 你要做的只是激发指定的动画, 接下来就交给 Core Animation 来渲染, 总之, 复杂的动画只需要几行代码就可以了. 哪些属性可以添加动画效果 根据 iOS 视图编程指南

IOS接入facebook详解

facebook 接入 1.在 facebook 后台 配置 ios 平台, 获取 fb appid store id 可以先随便找一个已存在的填入进去. 2.CocoaPods 引入几个核心库 pod 'FBSDKCoreKit', '~> 9.0.1' pod 'FBSDKLoginKit', '~> 9.0.1' pod 'FBSDKShareKit', '~> 9.0.1' pod 工程构建出 静态库丢到 /Users/XXX/Library/Developer/Xcode/De

iOS给border设置渐变色的方法实例

前言 本文将从4行代码出发给一个view设置渐变色,分别会谈到几个重要的渐变色相关属性,在使用过程中有几个需要特别关注的点. 给一个view的border设置渐变色是比较高阶的用法,希望本文可以在这个方面帮助到你. 给view设置渐变色 通过4行代码就可以给一个view设置渐变色: let view = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100)) let gradientLayer = CAGradientLaye

iOS tableView多输入框如何获取数据

前言 难得有点空暇的时间,写写文章,一壶小茶,惬意.扯远了,言归正传. 大家在做App开发的时候,肯定遇到过在一个列表中有多个让用户填写资料的情况,类似于这样的界面: iOS 如果一个tableView中有很多的输入框,而且cell是复用的,这个还有个提交功能 我的设计思路是这样的 1.建立一个Model对象,包含要输入的所有字段, 2.在建立一个cell,有个label和textField, 3.在初始化cell的地方,根据不同的indexRow,显示cell上不同的label,例如昵称.邮箱

iOS中从网络获取数据的几种方法的比较

IOS中获取网络数据一般有三种:1.NSURLCondition(已过时) 2.NSURLSession  3.三方库AFNetWorking NSURLSession 是苹果对NSULRCondition的替代品,NSURLSession比NSURLCondition多了 1.可配置的数据信息NSURLSessionConfiguration,NSURLSessionConfiguration使你可以设置你要请求的数据,通常的设置如缓存,也可以使用默认的配置信息defaultCongurati

ios获取数据之encodeURI和decodeURI的实例

在APP开发过程中,免不了要进行ios的数据处理,在ios传递数据的过程中,会出现JSON数据获取不到的情况,这时候就轮到encodeURI 和 decodeURI出马了. 1.encodeURI,decodeURI encodeURI:将字符串作为 URI 进行编码 •不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码( 即:- _ . ! ~ * ' ( ) ). •目的是对 URI 全部的编码,因此对在 URI 中具有特殊含义的 ASCII 标点符号(即:;

IOS 键盘挡住输入框的问题解决办法

IOS 键盘挡住输入框的问题解决办法 在iOS开发发现一个问题,有时输入框位于低出时,当编辑输入时,弹出的键盘会挡住输入框,令用户看不清楚实时的输入情况,使界面交互极度不友好. 经过查资料终于解决了这个问题. 解决思路: 1. 输入框监听UIControlEventEditingDidBegin事件,当用户开始输入时,将整个view上移. 2. 输入框监听UIControlEventEditingDidEnd事件,当用户结束输入时,将整个view下移,恢复到原位置. 输入框监听事件: [text

详解iOS应用开发中Core Data数据存储的使用

1.如果想创建一个带有coreData的程序,要在项目初始化的时候勾选中   2.创建完成之后,会发现在AppDelegate里多出了几个属性,和2个方法 复制代码 代码如下: <span style="font-size:18px;">    @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;  @property (readonly, strong,

iOS实现聊天输入框功能

经常使用微信聊天,没事儿就会想输入框的实现过程,所以抽空,也实现了一个输入框的功能: 经过封装,使用就非常的简单了,在需要的VC中,实现方法如下: - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor colorWithRed:0.92 green:0.92 blue:0.92 alpha:1.00]; self.keyView = [[DKSKeyboardView alloc] init

iOS tableView实现下拉图片放大效果

本文实例为大家分享了iOS实现下拉图片放大效果展示的具体代码,供大家参考,具体内容如下 #import "ViewController.h" #define kScreenbounds [UIScreen mainScreen].bounds #define kScreenWidth [UIScreen mainScreen].bounds.size.width #define kScreenHeight [UIScreen mainScreen].bounds.size.height

iOS tableview实现顶部拉伸效果

本文实例为大家分享了iOS tableview头部拉伸效果展示的具体代码,例如探探个人信息界面拉伸效果,下拉头像放大 代码: // // PersonController.m // Spread // // Created by qiuxuewei on 16/3/21. // Copyright © 2016年 邱学伟. All rights reserved. // #import "PersonController.h" @interface PersonController (

iOS中的地理位置的获取及plist设置方法

1.在前台的时候获取地理位置信息 ios 8/9 在info.plist中配置NSLocationWhenInUseUsageDescription的值,否则上面的方法无效 调用.requestWhenInUseAuthorization()获取前台获取地理位置权限 调用.startUpdatingLocation() 代码示例 class ViewController: UIViewController { lazy var locateM : CLLocationManager = { le

java从命令行获取数据的三种方式代码实例

这篇文章主要介绍了java从命令行获取数据的三种方式代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 第一种:利用Scanner对象 import java.util.Scanner; public class TestInputOuput { public static void main(String[] args) { System.out.println("请输入:"); Scanner inp = new Scanne

MySQL 随机函数获取数据速度和效率分析

在mysql中带了随机取数据的函数,在mysql中我们会有rand()函数,很多朋友都会直接使用,如果几百条数据肯定没事,如果几万或百万时你会发现,直接使用是错误的.下面我来介绍随机取数据一些优化方法. SELECT * FROM table_name ORDER BY rand() LIMIT 5; rand在手册里是这么说的: RAND() RAND(N) 返回在范围0到1.0内的随机浮点值.如果一个整数参数N被指定,它被用作种子值. mysql> select RAND(); -> 0.