iOS 函式響應式程式設計 (ReactiveCocoa)– 前篇

發表於2016-06-23

前言

近來,Q群的幾個朋友談起如何使用ReactiveCocoa(以下簡稱RAC)開發的問題。大家覺得RAC很好,但不知如何運用它。在此整理一些對RAC的看法,希望對學習RAC的朋友有所幫助。本篇是前篇,主要涉及以下內容。

  • 現有的程式設計問題
  • 為何出現了這些問題
  • 程式設計思想的變化

現有的程式設計問題

  1. 狀態量問題(類似Cache問題)
    在開發中時常需要一些狀態量來輔助處理事務。比如:按下登入按鈕後發起請求時需要一個狀態量(isRequesting)來標註正在請求。

    11

    狀態量問題

    但是由於isRequesting的改變相對隨意,也時常會忘記對它正確賦值,導致難以維護。這也就跟Cache中的難點(難以知道何時去更新Cache中的值)一樣。另外,當狀態量多起來時便會出現組合爆炸的問題(狀態成指數級增長),不利於擴充套件及維護。

  2. Controller爆炸問題
    隨著程式邏輯複雜度的提高,你是否也發現了App中一些ViewController的程式碼行數急劇增多,達到了2,3千行,甚至更多。這帶來了許多問題:1.不利於後續維護2.不利於支撐UI的變動3.不利於複用 4….
  3. 訊息傳遞機制方式繁多,帶來的選擇性問題
    iOS 開發中有著各種訊息傳遞機制,包括 KVO、block、Notification、delegation以及 target-action 方式。各種訊息傳遞機制使得開發者在做具體選擇時感到困惑,雖然有不少大牛分享了他們選擇的經驗(如:開發該選擇Blocks還是Delegates),但是在開發中始終覺得繁瑣。重點是如果選擇錯了方式,極不利於程式碼質量的保證。

為何出現了這些問題

12

1

2

2

3

3

從上面幾張圖我們可以看出,app其實是一個輸入-》處理-》輸出的過程。而它隨著輸入輸出的增多,開發的難度也越來越大。抽象一點來講就是變化越多,控制越難。

傳統的指令式程式設計,是以命令為主的,給機器提供一條又一條的命令序列讓其原封不動的執行,這就限制了程式設計的靈活性。
變化(輸入、輸出)越來越多-》分支越來越多-》狀態量問題
變化越來越多-》Handler處理的實務越來越多-》Controller爆炸問題(可通過MVVM模式解決)
變化越來越多-》需要不同的訊息處理機制-》訊息傳遞機制方式的選擇問題
……

既然指令式程式設計不能滿足我們的需求,那便尋求解決之法。於是我們想到了Functional Reactive Programming。


程式設計思想的變化

最近關於是否使用RAC的討論非常多。相當一部分的原因是RAC的學習成本高在團隊協作中需要每個人都學會使用。使用了一段時間後,個人覺得RAC學習成本高的原因是程式設計思想上的改變。
RAC運用的響應式程式設計(Functional Reactive Programming,以下簡稱FRP)與傳統的指令式程式設計思想差異較大。下面我們先來了解一下RAC使用的FRP思想。

RAC中的函式式思想

  1. 高階函式:函式作為引數來回傳遞。在oc中,block是被廣泛使用的引數傳遞,它實際上是匿名函式。
    例:

    44

    高階函式

    上面的例子中先使用filter(過濾)判斷value是否有“catch”字首,然後使用map(對映)將值對映成no more,最後輸出。不難看出例子中的filter 和 map block正是高階函式的應用。

  2. 惰性求值:只有當被使用到時,才會對其求值。在RAC中訊號只有被訂閱了,才會觸發
    例:

    55

    惰性求值

    將例子中的訂閱部分註釋,會發現雖然username改變了但是filter 和map不會觸發,這就是惰性求值思想的應用。
    在RAC中將未被訂閱的訊號稱為“冷訊號”,將已被訂閱的訊號稱為“熱訊號”
    例2:

    66

    惰性求值2

    RACSequence只有當被使用到時,才會對其求值(當註釋掉訂閱的時候,斷點是不觸發的),這也是惰性求值思想的應用。

RAC中的響應式思想

響應式程式設計是一種和事件流有關的程式設計模式,關注導致狀態值改變的行為事件,一系列事件組成了事件流。一系列事件是導致屬性值發生變化的原因。FRP非常類似於設計模式裡的觀察者模式
例:

77

RAC中的響應式思想

在傳統命令式的程式設計中可解讀成:a是 b + c 表示式的值。
而在響應式的程式設計中應解讀成:建立了一個動態的資料流關係(當c或者b的值發生變化時,a的值自動發生變化)。


小結

本篇概述了RAC與傳統程式設計方式的區別,下一篇開始,我們將利用RAC來開發一個完整的應用,以此來邊掌握RAC的知識。這期就到這了,下期見。

相關文章