函數(shù)式響應(yīng)式編程概述

函數(shù)式響應(yīng)式編程概述

  • 滿足函數(shù)式的一些特性;

    如何看待計算,如何避免使用狀態(tài)量,

  • 面向離散事件流

    每個對象是個離散事件流。

  • 離散事件流操作

什么是ReactiveCocoa?

  • Github Mac客戶端副產(chǎn)物
  • FRP在Cocoa框架下的實現(xiàn)
  • 富含了Cocoa框架多種組件
  • 提供基于時間變化的數(shù)據(jù)流的組合和變換
  • 簡稱RAC

如何理解基于時間變化的數(shù)據(jù)流?

流與數(shù)組.png

數(shù)組:是基于空間變化的數(shù)組;

流:是基于時間變化的數(shù)據(jù)流;

都要考慮:如何創(chuàng)建-如何遍歷-如何停止遍歷

數(shù)組:可以存在一個數(shù)組內(nèi)部封裝一個數(shù)組,稱為多維數(shù)組;
流:存在一個流內(nèi)部封裝另一個流,一個流稱為一階,多個嵌套的流稱為高階數(shù)據(jù)流;

基于時間變化的數(shù)據(jù)流可操作范圍

基于時間的數(shù)據(jù)流.png

流的更多操作

流的更多操作.png

函數(shù)式編程4特性

  • 閉包&高階函數(shù)
  • 惰性計算
  • 不改變狀態(tài)
  • 遞歸

高階函數(shù)

入?yún)⒑头祷刂刀际呛瘮?shù),稱這個函數(shù)是高階函數(shù)。

閉包

FRP中函數(shù)是第一類,和變量等同的概念,int a = 0;,如果上下文當中有一個a,不管a現(xiàn)在的值是多少,我在函數(shù)中會用到a將其捕獲進來,讓其參與計算,這就意味著每次a不同的時候,就會產(chǎn)生不同的函數(shù),這種情況下就稱為閉包

惰性計算

在使用時才會去計算的函數(shù)模型。

ReactiveCocoa基礎(chǔ)知識

核心框架

  • RACSteam RACSequence RACSignal

  • RACSubscriber

  • RACDisposable

  • RACScheduler

  • Cocoa框架適配工具

RACStream.png

Sequence Vs Signal

  • Pull-driver vs Push-driver

    Pull-driver 類似于你去看一本書,你想讀多少頁,書就提供多少頁,是你驅(qū)動書進行下去的。Push-driver 類似于你看電視,電視不會因為你的任何動作而有所停留,會一直播放節(jié)目,相當于一直push。

  • Data vs Event

    Sequence是一個id類型只包含數(shù)據(jù),Signal是一個id類型,基于信號和事件,信號發(fā)出的值不能只是值,還需要有一些狀態(tài)。signal把數(shù)據(jù)包含在value里.

  • 其他差異

    Sequence 和 Signal都是基于惰性計算的,效率各有不同,Sequence在空間中是連續(xù)的,進行大量的運算CPU消耗會比較高,Signal是離散的,離散就可以把計算分攤在很多的CPU循環(huán)的時間上

RACSequence使用示例

void sequence() {
    //創(chuàng)建三種方式
    RACSequence *seq1 = [RACSequence return:@1];
    RACSequence *seq2 = [RACSequence sequenceWithHeadBlock:^id _Nullable{
        return @1;
    } tailBlock:^RACSequence * _Nonnull{
        return seq1;
    }];
    RACSequence *seq3 = @[@1,@2,@3].rac_sequence;
    
    //變換
    RACSequence *mappedSeq = [seq1 map:^id _Nullable(NSNumber *  _Nullable value) {
        return @(value.integerValue * 3);
    }];
    RACSequence *concatedSeq = [seq2 concat:mappedSeq];
    RACSequence *mergedSeq = [RACSequence zip:@[concatedSeq, seq3]];
    NSLog(@"head is %@",mergedSeq.head);
    
    //遍歷
    for (id value in mergedSeq) {
        NSLog(@"value is %@", value);
    }
}

RACSignal

- (void)signalExample
{
    //創(chuàng)建
    RACSignal *signal1 = [RACSignal return:@"hello"];
    RACSignal *signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [subscriber sendNext:@1];
        [subscriber sendNext:@2];
        [subscriber sendCompleted];
        return nil;
    }];
    RACSignal *signal3 = RACObserve(self, value);
    
    //變換
    RACSignal *mappedSignal = [signal1 map:^id _Nullable(NSString*  _Nullable value) {
        return [value stringByAppendingString:@" world"];
    }];
    RACSignal *concatedSignal = [mappedSignal concat:signal2];
    RACSignal *mergeSignal = [RACSignal merge:@[concatedSignal, signal3]];
    
    //遍歷
    [mergeSignal subscribeNext:^(id  _Nullable x) {
        NSLog(@"next is %@", x);
    } completed:^{
        NSLog(@"completed");
    }];
}

Signal Subscriber Disposable

signal_subscriber_disposable.png

Subscriber訂閱Signal,寫的一些值,這些Block塊由Subscriber持有,Disposable負責在不持有的時候斷開。

Scheduler

  • 用來做調(diào)度

    什么時間在什么線程中執(zhí)行就稱為調(diào)度

  • 代替GCD

  • 異步與并發(fā)

總結(jié)

怎么理解函數(shù)式語言中的引用透明?

數(shù)學(xué)里的概念向計算機里的投射,引用透明表示一個函數(shù)具有數(shù)學(xué)中的函數(shù)意義,也就是說這個函數(shù)只根據(jù)他的因變量(參數(shù))而產(chǎn)生結(jié)果,即這個函數(shù)在執(zhí)行的過程中既不改變這個變量,也不基于這個變量。使用相同的參數(shù)對這樣的一個函數(shù)進行多次調(diào)用,會得到相同的結(jié)果。

函數(shù)式語言主張不變量的原因是什么?

  • 為了保證跟數(shù)學(xué)模型的親密性。
  • 編譯器更好的優(yōu)化
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容