Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >函数响应式编程及ReactiveObjC学习笔记 (二)

函数响应式编程及ReactiveObjC学习笔记 (二)

作者头像
周希
发布于 2019-10-15 03:46:10
发布于 2019-10-15 03:46:10
50600
代码可运行
举报
文章被收录于专栏:APP自动化测试APP自动化测试
运行总次数:0
代码可运行

之前我们初步认识了RAC的设计思路跟实现方式, 现在我们再来看看如果使用它以及它能帮我们做什么

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
One of the major advantages of RAC is that it provides a single, unified approach to dealing with asynchronous behaviors, including delegate methods, callback blocks, target-action mechanisms, notifications, and KVO.

官方是这样说的, RAC为我们提供了简单便捷实现代理 / block回调 / 事件 / 通知 / KVO的方式

我们先看RAC如何帮助我们快速实现KVO

首先我们新建一个Student类, 给它一个age的属性

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#import <Foundation/Foundation.h>

@interface Student : NSObject

@property (nonatomic, strong) NSString *age;

@end

下面我们看一个简单的如何使用RAC来实现KVO

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    Student *stu = [[Student alloc] init];
    
    // RAC KVO
    [RACObserve(stu, age) subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"stu的age改变为: %@", x);
    }];
    
    stu.age = @"10";

运行看看:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2017-07-23 11:35:19.704 RAC[67362:13075201] stu的age改变为: (null)
2017-07-23 11:35:19.704 RAC[67362:13075201] stu的age改变为: 10

很方便对吧, 不用我们去add observe, 不用出来观察事件, 也不用我们去移除关注

不过大家注意到了没, 这里添加关注后block立即执行了一次, 大家可以依据实际项目情况加个条件判断做处理.

这里其实RAC还为我们提供了除了subscriber以外的操作, 后面再介绍给, 现在我们主要先来看RAC是怎么替我们做KVO的

我们再看看RAC如何帮我们实现target-action

我们创建一个项目, 在controller中添加一个button, 然后给button添加一个点击事件

如果是常规写法的话, 在创建完button后创建一个点击响应方法, 然后通过addTarget把响应方法跟button及事件绑定到一起

大概类似这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[button addTarget:self action:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside];

- (void)btnAction {
    
    NSLog(@"点击了按钮");
}

在上一篇我们提到过这样的劣势, 当代码比较多的时候结构容易乱, 维护的时候也不好查找方法

我们看看RAC如何帮我们优雅的实现

RAC为我们提供了rac_signalForControlEvents来处理UIControllerEvent, 我们试试看

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    [[button
      rac_signalForControlEvents:UIControlEventTouchUpInside]
      subscribeNext:^(__kindof UIControl * _Nullable x) {
          
          NSLog(@"%@", x);
      }];

因为不知道这里的x是什么, 我们直接打印看看结果

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2017-07-23 12:05:59.654 RAC[67611:13189769] <UIButton: 0x7f95e0d069f0; frame = (157 350.5; 100 35); opaque = NO; layer = <CALayer: 0x6080000269a0>>

当我们点击按钮打印了上面这些, 是我们创建的button对象

那么加入需要点击的时候给button更换背景图片或者标题就可以在这里处理了, 我们用改变颜色举例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    [[button
      rac_signalForControlEvents:UIControlEventTouchUpInside]
      subscribeNext:^(__kindof UIControl * _Nullable x) {
          
          x.backgroundColor = [UIColor redColor];
      }];

运行后, 就可以看到如果点击按钮背景就会变成红色, 如果有点击事件也可以放在这里

但如果点击后要处理的逻辑比较多, 代码超过三行建议大家单独写一个方法供调用, 以免破坏代码的结构

RAC这样的使用方式, 让我的代码逻辑更加清晰紧凑了, 我们再看一个添加手势的例子

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
    
    [[tap
     rac_gestureSignal]
     subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
         
         NSLog(@"点击了屏幕");
         NSLog(@"x: %@", x);
     }];
    
    [self.view addGestureRecognizer:tap];

运行看看:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2017-07-23 12:15:59.246 RAC[67766:13231274] 点击了屏幕
2017-07-23 12:15:59.247 RAC[67766:13231274] x: <UITapGestureRecognizer: 0x6000001a5160; state = Ended; view = <UIView 0x7fb932d03780>; target= <(action=sendNext:, target=<RACPassthroughSubscriber 0x60800003a920>)>>

这里x是一个手势, 我们可以直接拿来使用, 比如我们改变下添加手势这个view的颜色

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
    
    [[tap
     rac_gestureSignal]
     subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
         
         NSLog(@"点击了屏幕");
         NSLog(@"x: %@", x);
         x.view.backgroundColor = [UIColor redColor];
     }];
    
    [self.view addGestureRecognizer:tap];

这样手势的初始化, 方法等等都在一起, 让代码一目了然

接下来我们看看RAC如何帮我们实现通知的

我们常规的通知应该是这样, 在要接收通知的地方添加关注通知并写上通知事件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notiAction) name:@"noti" object:nil];

- (void)notiAction {
    
    NSLog(@"接到了通知");
}

然后在对应的地方发送通知

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[[NSNotificationCenter defaultCenter] postNotificationName:@"noti" object:nil userInfo:nil];

RAC会怎么帮我们实现呢?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    [[[NSNotificationCenter defaultCenter]
     rac_addObserverForName:@"noti" object:nil]
     subscribeNext:^(NSNotification * _Nullable x) {
         
         NSLog(@"接到了通知");
     }];

发送通知iOS已经很简单了, RAC没有做重复工作但帮我们把添加关注通知的方法改进了, 可以让事件和通知关注在一起

这样接口就清晰了

那么RAC如果帮我们实现代理呢?

我用UIAlertView给大家举个例子, 虽然苹果已经不推荐用这个 不过我们拿来当例子用用看

先写一个常规的AlertView

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#import "ViewController.h"
#import <ReactiveObjC.h>

@interface ViewController ()<UIAlertViewDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"RAC" message:@"RAC Delegate Test" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];
    
    [alertView show];
    
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    
    if (buttonIndex == 0) {
        
        NSLog(@"点击了Cancel按钮");
    } else {
        
        NSLog(@"点击了Ok按钮");
    }
}

@end

初始化alertView, 实现代理方法 这是我们常规的用法

那么我们再看看RAC如何做

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#import "ViewController.h"
#import <ReactiveObjC.h>

@interface ViewController ()<UIAlertViewDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"RAC" message:@"RAC Delegate Test" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];
    
    [[self
     rac_signalForSelector:@selector(alertView:clickedButtonAtIndex:) fromProtocol:@protocol(UIAlertViewDelegate)]
     subscribeNext:^(RACTuple * _Nullable x) {
         
         NSLog(@"%@", x);
     }];
    
    [alertView show];
    
}

@end

RAC为我们提供了一个rac_signalForSelector: fromProtoc方法帮我们实现代理

我们把x打印看看

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2017-07-23 12:53:07.138 RAC[68380:13356332] <RACTuple: 0x6080000149f0> (
    "<UIAlertView: 0x7fc7dfc0c620; frame = (0 0; 0 0); layer = <CALayer: 0x6000002218a0>>",
    1
)

我们看看这个RACTuple

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@interface RACTuple : NSObject <NSCoding, NSCopying, NSFastEnumeration>

@property (nonatomic, readonly) NSUInteger count;

/// These properties all return the object at that index or nil if the number of 
/// objects is less than the index.
@property (nonatomic, readonly, nullable) id first;
@property (nonatomic, readonly, nullable) id second;
@property (nonatomic, readonly, nullable) id third;
@property (nonatomic, readonly, nullable) id fourth;
@property (nonatomic, readonly, nullable) id fifth;
@property (nonatomic, readonly, nullable) id last;

打印看看

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"RAC" message:@"RAC Delegate Test" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];
    
    [[self
     rac_signalForSelector:@selector(alertView:clickedButtonAtIndex:) fromProtocol:@protocol(UIAlertViewDelegate)]
     subscribeNext:^(RACTuple * _Nullable x) {
         
         NSLog(@"%@", x);
         NSLog(@"first: %@", x.first);
         NSLog(@"second: %@", x.second);
         NSLog(@"third: %@", x.third);
         NSLog(@"fourth: %@", x.fourth);
         NSLog(@"fifth: %@", x.fifth);
         NSLog(@"last: %@", x.last);
     }];
    
    [alertView show];

结果为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2017-07-23 16:29:26.089 RAC[68525:13409884] first: <UIAlertView: 0x7f814e604420; frame = (0 0; 0 0); layer = <CALayer: 0x60800003a3e0>>
2017-07-23 16:29:26.090 RAC[68525:13409884] second: 1
2017-07-23 16:29:26.090 RAC[68525:13409884] third: (null)
2017-07-23 16:29:26.090 RAC[68525:13409884] fourth: (null)
2017-07-23 16:29:26.091 RAC[68525:13409884] fifth: (null)
2017-07-23 16:29:26.091 RAC[68525:13409884] last: 1

第一个是alert本身, 第二个是index, 然后可以按我们的需要做处理了

另外要注意的是用RAC写代理是有局限的,它只能实现返回值为void的代理方法

先到这里, 现在我们知道我们能用RAC做什么了

下次我们继续看RAC的具体用法

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-07-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
iOS开发·runtime原理与实践: 关联对象篇(Associated Object)(应用场景:为分类添加“属性”,为UI控件关联事件Block体,为了不重复获得某种数据)
分类(category)与关联对象(Associated Object)作为objective-c的扩展机制的两个特性:分类,可以通过它来扩展方法;Associated Object,可以通过它来扩展属性;
陈满iOS
2018/09/10
3K0
iOS开发·runtime原理与实践: 关联对象篇(Associated Object)(应用场景:为分类添加“属性”,为UI控件关联事件Block体,为了不重复获得某种数据)
ReactiveCocoa函数响应式编程-基础篇目录:一、了解函数响应式编程二、ReactiveCocoa简介三、ReactiveCocoa集成四、ReactiveCocoa信号理解五、Reactiv
一直以来,都很想学学ReactiveCocoa这个神奇的技术,但是最后都由于各种原因搁置了。这次终于也认真的研究一番,把自己学习心得整理出来留个记录。 目录: 一、了解函数响应式编程 二、React
梧雨北辰
2018/04/24
7350
ReactiveCocoa函数响应式编程-基础篇目录:一、了解函数响应式编程二、ReactiveCocoa简介三、ReactiveCocoa集成四、ReactiveCocoa信号理解五、Reactiv
ReactiveCocoa 简单用法
ReactiveCocoa网上资料很多,今天就介绍一下ReactiveCocoa简单的用法。
赵哥窟
2020/07/16
8800
ReactiveCocoa 进阶
所有的信号(RACSignal)都可以进行操作处理,因为所有操作方法都定义在RACStream.h中,因此只要继承RACStream就有了操作处理方法。
零式的天空
2022/03/23
1K0
ReactiveCocoa,最受欢迎的iOS函数响应式编程库(2.5版),没有之一!
简介 项目主页: ReactiveCocoa 实例下载: https://github.com/ios122/ios122 简评: 最受欢迎,最有价值的iOS响应式编程库,没有之一!iOS MVVM模
ios122
2018/01/02
1.2K0
ReactiveCocoa(二)
前言 通过ReactiveCocoa(一)的学习,相信大家对ReactiveCocoa有了一些基本认识吧。下面就让我们来学习ReactiveCocoa的一些基本使用吧! ReactiveCocoa基本使用 代替代理 在ReactiveCocoa(一)中讲到可以通过RACSubject代替代理,我们也可以通过rac_signalForSelector同样代替代理。 代码演练 // 需求:自定义redView,监听红色view中按钮点击 // 之前都是需要通过代理监听,给红色View添加一个代理属性,点击按钮的
Scott_Mr
2018/07/05
6110
ReactiveCocoa 中 RACCommand 底层实现分析
在ReactiveCocoa 过程中,除去RACSignal和RACSubject这些信号类以外,有些时候我们可能还需要封装一些固定的操作集合。这些操作集合都是固定的,每次只要一触发就会执行事先定义好的一个过程。在iOS开发过程中,按钮的点击事件就可能有这种需求。那么RACCommand就可以实现这种需求。
一缕殇流化隐半边冰霜
2018/08/30
1.1K0
ReactiveCocoa 中 RACCommand 底层实现分析
函数响应式编程及ReactiveObjC学习笔记 (三)
今天先不去分析它的核心代码, 我们先看看ReactiveObjC库里面一些特别的东西, 如果大家点开ReactiveObjC目录应该会看到很多category, 今天我们先来看看这些
周希
2019/10/15
9240
函数响应式编程及ReactiveObjC学习笔记 (三)
函数响应式编程及ReactiveObjC学习笔记 (四)
UIImagePickerController+RACSignalSupport.h
周希
2019/10/15
9170
函数响应式编程及ReactiveObjC学习笔记 (四)
函数响应式编程及ReactiveObjC学习笔记 (-)
最近无意间看到一个视频讲的ReactiveObjC, 觉得挺好用的 但听完后只是了解个大概.
周希
2019/10/15
8980
ReactiveCocoa函数响应式编程-应用篇目录:一、RAC中常用的类4.RACCommand:用于处理事件的类二、RAC常用的宏定义三、RAC中关于信号的常用操作四、RAC常用的处理事件响应的方
使用RAC其实就是一个创建信号订阅信号的过程。上篇ReactiveCocoa函数响应式编程-基础篇,主要简单介绍了RAC的信号机制,本篇则以信号为核心,就信号常用的类、操作信号的方法,替换响应处理等方面总结RAC的使用。 目录: 一、RAC中常用的类 二、RAC中常用的宏 三、RAC中信号的常用操作 四、RAC常用的处理事件响应的方法 五、本篇总结 本篇还提供了关于RAC使用的两个测试工程,结合代码学习更加直观: 项目1: 1.测试RAC对信号的各类操作。 2.使用RAC改进一个普通的登录界面
梧雨北辰
2018/04/24
3.2K0
ReactiveCocoa函数响应式编程-应用篇目录:一、RAC中常用的类4.RACCommand:用于处理事件的类二、RAC常用的宏定义三、RAC中关于信号的常用操作四、RAC常用的处理事件响应的方
iOS函数响应式编程以及ReactiveCocoa的使用
打算在项目中大面积使用RAC来开发,所以整理一些常用的实践范例和比较完整的api说明方便开发时随时查阅
用户7451029
2020/06/16
2.1K2
iOS函数响应式编程以及ReactiveCocoa的使用
【IOS开发高级系列】MVVM—ReactiveCocoa架构设计专题(二)
        Streams 表现为RACStream类,可以看做是水管里面流动的一系列玻璃球,它们有顺序的依次通过,在第一个玻璃球没有到达之前,你没法获得第二个玻璃球。
江中散人_Jun
2023/10/16
3900
【IOS开发高级系列】MVVM—ReactiveCocoa架构设计专题(二)
iOS手势与变形
手势在用户交互中有着举足轻重的作用,这篇文字简单的介绍了iOS中的手势,并通过手势对控件进行变形处理。若有错误,或不同的见解,请指正! 手势 ---- iOS手势分为下面这几种: UITapGestureRecognizer(点按) UIPanGestureRecognizer(拖动) UIScreenEdgePanGestureRecognizer (边缘拖动) UIPinchGestureRecognizer(捏合) UIRotationGestureRecognizer(旋转) UILongPr
BY
2018/05/11
1.9K0
【IOS 开发】基本 UI 控件详解 (UISegmentedControl | UIImageView | UIProgressView | UISlider | UIAlertView )
转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/50163725
韩曙亮
2023/03/27
3.4K0
【IOS 开发】基本 UI 控件详解 (UISegmentedControl | UIImageView | UIProgressView | UISlider | UIAlertView )
iOS_ReactiveObjC_Observe 观察 基本类型变量
因为ReactiveObjC只能监听NSObject类型的数据,所以一般为了能监听BOOL值的类型,我们会用NSNumber来实现BOOL。
mikimo
2022/07/20
4440
iOS 回调只会用Block和Delegate?
写一个View,View上放一个按钮,如果按钮点击后要调用Controller的方法可以用Block或者委托实现。除了Block和委托外还可以使用ReactiveObjC
赵哥窟
2021/12/16
6140
iOS ReactiveCocoa(RAC)学习详解
概述:     ReactiveCocoa(简称为RAC),是由Github开源的一个应用于iOS和OS开发的一个框架,有时间,自己也了解学习了一下这个框架的一些基本的应用,其实你要学的话网上是有很多很多的博客给你去仔细的学习这个框架,我也把自己看到的觉得很不错的博客整理出来,方便大家以后学习也方便自己巩固这些知识! ReactiveCocoa是做什么的?    引述自己学习的《最快让你上手ReactiveCocoa之基础篇》这篇博客里面的概述,说说 ReactiveCocoa 的作用; 在我们iOS开发过
Mr.RisingSun
2018/01/10
2.2K0
ReactiveCocoa(一)
前言 之前总听别人说什么Reactive Cocoa + MVVM,但是没有找到讲解Reactive Cocoa相关的资料。结果进入新公司,项目里面有部分代码使用到了Reactive Cocoa,所以笔者在这记录自己学习Reactive Cocoa的笔记,同时也希望大家通过阅读这篇文章能学到点什么。 Reactive Cocoa简介 Reactive Cocoa(简称RAC,PS:不是ARC(自动引用计数)),是由Github开源的一个应用于iOS和OS开发的新框架,cocoa是苹果整套框架的简称,因此很多
Scott_Mr
2018/05/16
8410
iOS_11_tableViewCell使用alertView变更数据
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/117667.html原文链接:https://javaforall.cn
全栈程序员站长
2022/07/05
4930
iOS_11_tableViewCell使用alertView变更数据
推荐阅读
相关推荐
iOS开发·runtime原理与实践: 关联对象篇(Associated Object)(应用场景:为分类添加“属性”,为UI控件关联事件Block体,为了不重复获得某种数据)
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验