国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

ReactiveCocoaTutorial[2]="百變RACStream";

2019-11-14 20:42:40
字體:
供稿:網(wǎng)友

Reactive Cocoa Tutorial 系列,轉(zhuǎn)載請(qǐng)注明該文源地址 -- by sunny


  · Overview

  在RAC下開發(fā)干的最多的事就是建立RACSignal和subscribe RACSignal了,它是RAC的核心所在。本篇介紹了RAC的運(yùn)作原理和設(shè)計(jì)思路,從函數(shù)式編程形成的RACStream繼而介紹它的子類 - RAC最核心的部分RACSignal。

· 函數(shù)式編程

  我們知道Reactive Cocoa是函數(shù)式編程(Functional PRograming)(FP)思想的實(shí)現(xiàn)。FP有一套成熟的理論,這里只講講我個(gè)人理解吧。

  我覺得FP就是“像計(jì)算函數(shù)表達(dá)式一樣來解決一個(gè)問題”,舉個(gè)栗子,中學(xué)題:

已知:f(x) = 2sin(x + π/2), 求 f(π/2)的值。

  其中x是這個(gè)函數(shù)的輸入,f(x)為計(jì)算的輸出結(jié)果,求f(π/2)時(shí)給定了x自然能計(jì)算出個(gè)結(jié)果來(說實(shí)話我真忘了咋算了)

當(dāng)然,仔細(xì)看這個(gè)函數(shù),其實(shí)是可以分解成幾個(gè)小函數(shù)的:

f1(x) = x + π/2f2(x) = sin(x)f3(x) = 2x

  而原來的f(x)可以被小函數(shù)組合:

f(x) = f3(f2(f1(x)))

  所以不難得出這么個(gè)推論:要是我手上有足夠的基本函數(shù),我就能用上面的組合的方法組合出任意一個(gè)復(fù)雜的函數(shù)了。再想想事實(shí)上這些年來學(xué)數(shù)學(xué)的過程不就是在一個(gè)個(gè)積累基本函數(shù)的過程嘛,從基本運(yùn)算,到三角函數(shù),到乘方開方,再到微積分。基本函數(shù)越來越多,能解決的數(shù)學(xué)問題也越來越復(fù)雜。

  再來看一個(gè)函數(shù)是怎么構(gòu)成的,F(xiàn)P理論里叫monads,十分抽象,沒讀懂,但能理解出來:一個(gè)函數(shù)只要有一個(gè)對(duì)于輸入值的運(yùn)算方法一個(gè)返回值,就夠了。也容易理解,給它一個(gè)輸入,干點(diǎn)事情,給出一個(gè)輸出,就行了,當(dāng)然現(xiàn)實(shí)情況要復(fù)雜得多(比如說輸出值本身就是個(gè)函數(shù)?)有些函數(shù)是有輸入的條件的,比如原來數(shù)學(xué)解個(gè)函數(shù)時(shí)候經(jīng)常跟個(gè)作用域或者限制條件,比如f(x) = 10 / x , (x不為0),要是傳個(gè)0這個(gè)函數(shù)就認(rèn)為計(jì)算錯(cuò)誤。

  對(duì)于像上面栗子的函數(shù),每個(gè)函數(shù)都能接收上一個(gè)函數(shù)輸出的結(jié)果,作為自己的輸入,這樣才能嵌套生成最終結(jié)果,同時(shí),計(jì)算的順序也是一定從里向外,所以換個(gè)寫法可以寫成:

start ---x--> f1(x) --(temp value1)--> f2(temp value1) --(temp value2)--> f3(temp value2) ---> result

  于是乎嵌套就被表示成了序列,來個(gè)高大上的名字怎么樣,就叫(Stream)

·RACStream

  這就是RACStream所表示的含義。

  按照上面說的,其實(shí)RACStream的名字有點(diǎn)點(diǎn)歧義,對(duì)于一個(gè)RACStream對(duì)象,它在意義上等同于上面的f1(x),f2(x),f3(x),而不是那一大串整體,表示整體的應(yīng)該是最外層的和f(x)對(duì)應(yīng)的那個(gè)對(duì)象,叫個(gè)RACStreamComponent比較好?理解時(shí)候得注意下。

  所以作為一個(gè)基本函數(shù)的RACStream應(yīng)該至少應(yīng)該有:

    1. 怎么傳入值
    2. 怎么返回值
    3. 怎么與其他函數(shù)組合
    4. 怎么實(shí)現(xiàn)函數(shù)的作用域(監(jiān)測輸入值來做處理)
    5. 這函數(shù)叫啥- -

  得益于在Objc下實(shí)現(xiàn),所以輸入輸出的“值”都用個(gè)id類型就行了,遇到多個(gè)值的組合就用RACTurple(可以把多個(gè)值壓包和解包,類比WINRAR),1和2解決

  RACStream從實(shí)例變量來看只有一個(gè)name,當(dāng)然它也只應(yīng)該有個(gè)name - -,5解決

  里面重點(diǎn)問題就是上面的3和4了。由于函數(shù)組合之后仍然是個(gè)函數(shù),所以也很容易理解兩個(gè)Stream對(duì)象的組合其實(shí)就是生成一個(gè)新的Stream對(duì)象,它返回了分別由兩個(gè)子Stream先后運(yùn)算產(chǎn)生的最終結(jié)果

   觀摩一下RACStream定義的基本方法:

+ (instancetype)empty;+ (instancetype)return:(id)value;- (instancetype)bind:(RACStreamBindBlock (^)(void))block; // for 4- (instancetype)concat:(RACStream *)stream; // for 3- (instancetype)zipWith:(RACStream *)stream; // for 3

  RACStream作為一個(gè)描述抽象的父類,這幾個(gè)基本方法并沒有實(shí)現(xiàn),是由具體子類來實(shí)現(xiàn),RACStream的兩個(gè)子類分別是RACSignal和RACSequence

  +empty 是一個(gè)不返回值,立刻結(jié)束(Completed)的函數(shù),意思是執(zhí)行它之后除了立刻結(jié)束啥都不會(huì)發(fā)生,可以理解為RAC里面的nil。

  +return: 是一個(gè)直接返回給定值,然后立刻結(jié)束的函數(shù),比如 f(x) = 213

  -bind:是一個(gè)非常重要的函數(shù),在Rac Doc中被描述為‘basic primitives, particularly’,它是RACStream監(jiān)測“值”和控制“運(yùn)行狀態(tài)”的基本方法,個(gè)人認(rèn)為看注釋文檔不能理解它是干嘛的,而且bind英語“捆綁,綁定,強(qiáng)迫,約束”這幾個(gè)意思也感覺對(duì)不上,我覺得叫“綁架”倒是更貼切一點(diǎn)。在-bind:之后,之前的RACStream就處于被“綁架”的狀態(tài),被綁架的RACStream每產(chǎn)生一個(gè)值,都要經(jīng)過“綁架者”來決定:

1. 是否使這個(gè)RACStream結(jié)束(被綁架者是否還能繼續(xù)活著)

2. 用什么新的RACStream來替換被綁架的RACStream,傳出的結(jié)果也成了新RACStream產(chǎn)生的值(綁匪可以選擇再抓一個(gè)人質(zhì)放之前那個(gè)前面)

   舉個(gè)具體栗子,RACStream的 - take:方法,這個(gè)方法使一個(gè)RACStream只取前N次的值(有縮減):

- (instancetype)take:(NSUInteger)count {    Class class = self.class;        return [[self bind:^{ // self被綁架        __block NSUInteger taken = 0;        return ^ id (id value, BOOL *stop) { // 這個(gè)block在被綁架的self每輸出一個(gè)值得時(shí)候觸發(fā)            RACStream *result = class.empty;            if (taken < count) result = [class return:value]; // 未達(dá)到N次時(shí)將原值原原本本的傳遞出去            if (++taken >= count) *stop = YES; // 達(dá)到第N次值后干掉了被綁架的self            return result; // 將被綁架的self替換為result        };    }]];}

   -concat: 和 -zipWith: 就是將兩個(gè)RACStream連接起來的基本方法了:

  1. [A concat:B]中A和B像皇上和太子的關(guān)系,A是皇上,B是太子。皇上健在的時(shí)候統(tǒng)治天下發(fā)號(hào)施令(value),太子就候著,不發(fā)號(hào)施令(value),當(dāng)皇上掛了(completed),太子登基當(dāng)皇上,此時(shí)發(fā)出的號(hào)令(value)是太子的。
  2. [C zipWith:D]可以比喻成一對(duì)平等恩愛的夫妻,兩個(gè)人是“綁在一起“的關(guān)系來組成一個(gè)家庭,決定一件事(value)時(shí)必須兩個(gè)人都提出意見(當(dāng)且僅當(dāng)C和D同時(shí)都產(chǎn)生了值的時(shí)候,一個(gè)value才被輸出,CD只有其中一個(gè)有值時(shí)會(huì)掛起等待另一個(gè)的值,所以輸出都是一對(duì)值(RACTuple)),當(dāng)夫妻只要一個(gè)人先掛了(completed)這個(gè)家庭(組合起來的RACStream)就宣布解散(也就是無法湊成一對(duì)輸出時(shí)就終止)

· 然后呢?

  除了上面幾個(gè)基本方法,RACStream還有不少的Operation方法,這些操作方法的實(shí)現(xiàn)大都是組合基本的方法來達(dá)到特定的目的,雖然是RACStream這個(gè)基類實(shí)現(xiàn)的,但我覺得還是放在后面介紹RACSignal的時(shí)候作為它的使用方法來說比較合適,畢竟絕大多數(shù)編程的對(duì)象的都是RACStream的兩個(gè)子類,后面再展開介紹好了。

 


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 正安县| 桃江县| 洛川县| 社会| 昌图县| 大新县| 金堂县| 冷水江市| 宿州市| 神农架林区| 晋州市| 阿拉尔市| 建始县| 承德县| 洛阳市| 凤冈县| 赫章县| 化德县| 富宁县| 图木舒克市| 弥勒县| 汨罗市| 寻乌县| 通许县| 象山县| 霍州市| 公主岭市| 临安市| 浑源县| 志丹县| 吉林市| 玉林市| 肥西县| 锦屏县| 清远市| 天等县| 余江县| 德清县| 馆陶县| 东乌| 岳池县|