標籤:blog http io os ar for 2014 div sp
在PromiseKit中,裡面涉及了很多的遞迴操作,而遞迴操作,對於大部分人理解起來都是比較麻煩的(包括我),而github中一些高上大的第三方庫,無一不涉及了很漂亮的遞迴操作,因此理解遞迴操作是很必要的。如果想成為儘可能優秀的程式猿。
遞迴操作:自己調用自己,不停的壓棧,最後出棧。(說的簡單,但是還是理解起來還是比較複雜的) 我們來接著看看PromiseKit的遞迴操作,看看它的鏈式結構式怎麼樣實現的。 相信在上一章就可以瞭解到,then操作最後返回的是一個新的PMKPromise,然後返回的PMKPromise執行個體可以再次調用then方法,這就是一個鏈式結構了(如)。很簡單。如果僅僅是這種遞迴,那麼就沒必要寫這篇了。 來仔細看看它內部的遞迴操作,瞭解它最後是如何進行這麼多then得調用執行的,(它不是立刻調用then就執行了block的函數體,而是在之後的特定情況才執行的,比如UIAlertView 是在點擊按鈕的情況下進行執行的),還有看看它的值傳遞是如何進行的。 廢話不多說先貼代碼: resolved:pending 函數裡面的
dispatch_barrier_sync(_promiseQueue, ^{ if ((result = _result)) return; __block PMKPromiseFulfiller resolver; next = [PMKPromise new:^(PMKPromiseFulfiller fulfill, PMKPromiseRejecter reject) { resolver = ^(id o){ if (IsError(o)) reject(o); else fulfill(o); }; }]; [_handlers addObject:^(id value){ mkpendingCallback(value, next, q, block, resolver); }]; });
和一個PMKRsolve函數
static void PMKResolve(PMKPromise *this, id result) {void (^set)(id) = ^(id r){ NSArray *handlers = PMKSetResult(this, r); for (void (^handler)(id) in handlers) handler(r); }; if (IsPromise(result)) { PMKPromise *next = result; dispatch_barrier_sync(next->_promiseQueue, ^{ id nextResult = next->_result; if (nextResult == nil) { // ie. pending [next->_handlers addObject:^(id o){ PMKResolve(this, o); }]; } else set(nextResult); }); } else set(result);}
看到,set的block塊執行的操作是遍曆執行所有的儲存在_handlers的handler的block塊,還會把設定PMKResolved的result值,然後清空所有儲存的_handler的block塊。這是一個主體的塊,能夠讓我們的then中得block合理的執行,這個在上一章節已經說過了。 下面便是一個主體的遞迴操作了,下面看看這個遞迴的操作是怎麼樣的:1.判斷是否 result 是 PMKResolved2.如果不是PMKResolved,則調用set的block塊(參數是Result)3.如果是PMKResolved,則判斷result的nextResult,判斷它是否是PMKResolved4.如果不是PMKResolved,則調用set的block塊(參數是nextResult)5.如果是PMKResolved,則回到1 這是整個遞迴的過程,開啟整個無線迴圈的操作是2和4. 如果是UIAlertView執行個體,則直接會調用4的操作了。這樣就是最簡單的執行過程了。 我們想想,如果then後面接了好幾個then,那麼這個執行回事怎麼樣的,每個PMKResolved都會將他的handler執行完成,這樣每個then中得block塊就執行了,
dispatch_barrier_sync這個函數,保證了它是順序執行的。那麼它執行的順序是不是就是類似於我們一行一行代碼在執行一個個then中得block塊了。至於值傳遞,我們也再上面說到了。這裡就不在強調了。
最後遞迴比較難以理解,但是認真去解讀的話還是可以的,在國外,很多高校都是以lisp或者haskell這樣的函數式語言來接觸編程的,有的有scheme這種語言的課程,這些語言的主要思想就是遞迴。因此遞迴還是在他們深深的腦海裡的。許多情況下遞迴效率很高,代碼很簡潔。但是對於我們來說還是在不熟悉的情況下少用為妙。我也嘗試學學這樣一門語言,進行下頭腦風暴。
PromiseKit 解析 (二) 遞迴 IOS