Reactive cocoa 函数响应式编程概述

本文探讨了命令式编程、函数式编程及响应式编程的概念与特点,并通过实例介绍了ReactiveCocoa库中流的使用方法,包括RACSequence和RACSignal的创建、变换与遍历。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、2种编程方式

命令式编程:冯诺依曼   寄存机 计算器 (创建内存、计算内存、返回)

int factorial1(int x) {

    int result = 1;

    for (int i = 1; i <= x; ++i) {

        result *= i;}

    return result;

}

函数式编程:更推崇表达式 弱化语句 基于变量进行计算 不允许定义变量

int factorial2(int x) {

    if (x == 1) return 1;

    return x * factorial2(x - 1);

}

响应式编程:aotulayout(数学中的线相等式)

函数响应式编程:面向离散事件流,离散事件流操作(如excel的单元格)


二、流

FRPCocoa框架下的实现

提供基于时间变化的数据流的组合和变换


高阶函数:入参(是函数)   返回值(是函数)函数名

闭包:(函数跟变量等同) blockoc下闭包的实现

惰性计算: 在使用的时候才会计算

不改变状态: 不能够定义变量 (不用担心多线程改变这个变量,有多少核都能充分运用)

递归:调用函数


三、核心组件


- RACSteam:子类、RACSequenceRACSignal


- RACSequence:基于空间的数据流,更像数组和链表 Pull-driver:主动吸收  Data:id类型,里面可以是任意类型,sequence里可以嵌套sequence,时间上连续,消耗CPU较大时间缓慢


创建、变换、遍历

void sequence() {

    RACSequence *sequence1 = [RACSequence return:@1];

    RACSequence *sequence2 = [RACSequence sequenceWithHeadBlock:^id{

        return @2;

    } tailBlock:^RACSequence *{

        return sequence1;

    }];

    RACSequence *sequence3 = @[@1, @2, @3].rac_sequence; 数组桥接

    RACSequence *mappedSequence = [sequence1 map:^id(NSNumber *value) {

        return @(value.integerValue * 3);

    }];

    

    RACSequence *concatedSequence = [sequence2 concat:mappedSequence];

    RACSequence *mergedSequence = [RACSequence zip:@[concatedSequence,sequence3]];

    

    NSLog(@"head is %@", mergedSequence.head);

    for (id value in mergedSequence) {

        NSLog(@"value is %@", value);

    }

}


- RACSignal:基于时间的数据流,Push-driver:被动接受 Event:基于信号 4event 值、错误、终止、中断,把数据包含在value中,时间分散


创建、变换、遍历

void signalExample() {

    RACSignal *signal1 = [RACSignal return:@"hello"];

    RACSignal *signal2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        [subscriber sendNext:@1];

        [subscriber sendNext:@2];

        [subscriber sendCompleted];

        return nil;

    }];

    RACSignal *signal3 = RACObserve(someObject, frame);

    RACSignal *mappedSignal = [signal1 map:^id(NSString *value) {

        return [value stringByAppendingString:@" world"];

    }];

    RACSignal *concatedSignal = [mappedSignal concat:signal2];

    RACSignal *mergeSignal = [RACSignal merge:@[concatedSignal, signal3]];

    

    [mergeSignal subscribeNext:^(id x) {

        NSLog(@"next is %@", x);

    } completed:^{

        NSLog(@"completed");

    }];

}


- RACSubscriberSubscriber订阅Signal

- RACDisposableDisposableSignal的开关

- RACScheduler:用来做调度,代替GCD,异步与并发


- Cocoa框架适配工具


rac:适用于任何的异步场景 (解析json3D模型绘制到屏幕上,压缩解压缩等同步场景不适用)






1.函数式编程不是面向对象编程的升级版,是一种变成范式

2.组成链式调用的必要条件就是在方法里面返回一个可被链式编程调用的对象,并不一定是对象自己

3.响应式编程可以用C语言这样的语言实现


4.ReactiveCocoa使用了KVO,但不是基于KVO的一个开源库,离开KVO也能运行

5.ReactiveCocoa不是一个纯函数式编程的库

6.下面的函数由于有赋值但仍是一个纯函数,没有进行二次赋值


没有改变参数也没有利用外界的变量

typedef int(^FunctionType1)(int x);

typedef int(^FunctionType2)(int x, int y);


FunctionType1 someFunction(FunctionType2 func, int x, FunctionType1 valueMap) {

    

    int nextValue = valueMap(x);

    return ^int(int y) {

        return func(nextValue, y);

    };

}


7. Pull-driverPush-driver的区别?


pull-driverpush-dirver 的区别就是看书看直播的区别。 push-driver对未来的预期可以是清楚的,但是表示的是未来发生,而非随时发生。pull-driver的发生预期是清楚的。


8.怎么理解函数式语言中的引用透明?


根据参数产生结果,既不改变外部变量,也不基于外部变量,只是基于参数参数变化,引用透明就是指使用相同的参数对这样一个函数进行相同的调用,会得到相同的结果。基于引用透明,很多语言都能进行引用透明优化,不需要再次调用,只需存储结果


9.函数式语言主张不变量的原因是什么

任何数学模型中,不存在变量这一概念。变量不变,就没有一个很严格的执行顺序


10. 基于变量不可变(任何变量不允许二次赋值)来实现一个计算最大值的函数,定义如下

int max(int *array, int count)


(1)递归

 int max(int *array, int count){

     if (count < 1) return INT_MIN;

     if (count == 1) return array[0];

     int headMax = max(array, count - 1);  //取得前count-1的最大值

     return headMax > array[count - 1] ? headMax : array[count -1];  //最大值跟最后一个元素比较

 }

 

 (2) 高阶函数

 typedef int (^ReduceType)(int acc,int next);

 int fold(int *array, int count, ReduceType block, int first){

     if (count == 0) return first;

     return fold(array + 1, count - 1, block, block(first, array[0]));

     

 }

 

 void maxNumber(){

     int array[] = {1,2,3,4,5,9,-1};

     //    NSArray *arr = @[@1,@2];

     //    [arr subarrayWithRange:NSMakeRange(1, arr.count -1)];

     //求最大值

     int max = fold(array, sizeof(array) / sizeof(int), ^int(int acc, int next) {

         return acc > next ? acc : next;

     }, INT_MIN);

     //求最小值

     int min = fold(array, sizeof(array) / sizeof(int), ^int(int acc, int next) {

         return acc < next ? acc : next;

     }, INT_MAX);

     //求最乘积

     int multiply = fold(array, sizeof(array) / sizeof(int), ^int(int acc, int next) {

         return acc * next;

     }, 1);

     NSLog(@"max=%d",max);

 }

 

 11.自由发挥写一个高阶函数应用的例子,要求必须有返回函数的部分

# 例子中并没有包含返回函数的部分,可以用OCblock实现一个返回block的例子

 typedef BOOL (^ConditionType)(int a);

 //从一个数组中查找元素

 int find(int *array, int count, ConditionType finder){

     if (count == 0) return INT_MIN;

     if (finder(array[0])) {

         return array[0];

     }

     return find(array + 1, count - 1, finder);

 }

 

 //传入一个block用来判断,返回一个新的blocka传入之后判断取反进行返回

 ConditionType not(ConditionType block)

{

    return ^BOOL(int a){

        return !block(a);

    };

}

 

 void test(){

     int array[] = {1,2,3,4,5,9,-1};

     ConditionType even = ^BOOL(int v) {

         return v % 2 == 0;

     };

     int value = find(array, sizeof(array) / sizeof(int), even);

     NSLog(@"偶数 ------(%d) -------",value); //value = 2;

     int value2 = find(array, sizeof(array) / sizeof(int), not(even));

     NSLog(@"奇数 ------(%d) -------",value2); //value2 = 1;

 }

内容概要:本文介绍了奕斯伟科技集团基于RISC-V架构开发的EAM2011芯片及其应用研究。EAM2011是一款高性能实时控制芯片,支持160MHz主频和AI算法,符合汽车电子AEC-Q100 Grade 2和ASIL-B安全标准。文章详细描述了芯片的关键特性、配套软件开发套件(SDK)和集成开发环境(IDE),以及基于该芯片的ESWINEBP3901开发板的硬件资源和接口配置。文中提供了详细的代码示例,涵盖时钟配置、GPIO控制、ADC采样、CAN通信、PWM输出及RTOS任务创建等功能实现。此外,还介绍了硬件申领流程、技术资料获取渠道及开发建议,帮助开发者高效启动基于EAM2011芯片的开发工作。 适合人群:具备嵌入式系统开发经验的研发人员,特别是对RISC-V架构感兴趣的工程师和技术爱好者。 使用场景及目标:①了解EAM2011芯片的特性和应用场景,如智能汽车、智能家居和工业控制;②掌握基于EAM2011芯片的开发板和芯片的硬件资源和接口配置;③学习如何实现基本的外设驱动,如GPIO、ADC、CAN、PWM等;④通过RTOS任务创建示例,理解多任务处理和实时系统的实现。 其他说明:开发者可以根据实际需求扩展这些基础功能。建议优先掌握《EAM2011参考手册》中的关键外设寄存器配置方法,这对底层驱动开发至关重要。同时,注意硬件申领的时效性和替代方案,确保开发工作的顺利进行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值