ReactiveCocoa框架學習及資源整理

常用類

RACSignal類

// 創(chuàng)建一個信號
// 每當一個新的subscriber訂閱時考抄,會調用didSubscribe
// 內部實現(xiàn):
// 1. 調用RACDynamicSignal的createSignal:方法,并返回RACDynamicSignal實例對象
// 2. RACDynamicSignal的createSignal:方法內部臼朗,首先實例化一個RACDynamicSignal對象豹缀,然后將didSubscribe這個block塊copy一份保存在_didSubscribe變量中藤巢。
+ (RACSignal<ValueType> *)createSignal:(RACDisposable * _Nullable (^)(id<RACSubscriber> subscriber))didSubscribe

RACSignal(Subscription)

// 抽象方法,具體需要由子類去實現(xiàn)撵溃。
- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber;

// 訂閱subscriber的next事件疚鲤,當subscriber執(zhí)行next的block后,會執(zhí)行此處的block
// 方法內部實現(xiàn):
// 1. 根據(jù)傳入的參數(shù)nextBlock創(chuàng)建RACSubscriber類的實例對象o, 對象o持有nextBlock缘挑。
// 2. 調用subscribe:方法魂爪,如果調用者是子類RACDynamicSignal對象放航,會調用其子類方法subscribe:麻敌,并返回一個disposable
// 3. RACDynamicSignal的subscribe:方法內部:
// 3.1 創(chuàng)建RACCompoundDisposable對象disposable
// 3.2 根據(jù)self, subscriber(對象o),disposable三個參數(shù)生成一個RACPassthroughSubscriber對象subscriber孩革,
// 3.3 如果_didSubscribe有值,會使用RACScheduler的subscriptionScheduler方法獲取單例對象惶翻,并調用schedule:方法姑蓝,傳入一個block參數(shù),該block中會執(zhí)行_didSubscribe塊吕粗,并返回一個innerDisposable纺荧,添加到disposable中。
- (RACDisposable *)subscribeNext:(void (^)(ValueType _Nullable x))nextBlock;

// 訂閱'next'和'completed'事件
- (RACDisposable *)subscribeNext:(void (^)(ValueType _Nullable x))nextBlock completed:(void (^)(void))completedBlock;

// 訂閱'next','complete','error'事件
- (RACDisposable *)subscribeNext:(void (^)(ValueType _Nullable x))nextBlock error:(void (^)(NSError * _Nullable error))errorBlock completed:(void (^)(void))completedBlock;

// 訂閱'error'事件
- (RACDisposable *)subscribeError:(void (^)(NSError * _Nullable error))errorBlock;

// 訂閱'completed'事件
- (RACDisposable *)subscribeCompleted:(void (^)(void))completedBlock;

// 訂閱'next','error'事件
- (RACDisposable *)subscribeNext:(void (^)(ValueType _Nullable x))nextBlock error:(void (^)(NSError * _Nullable error))errorBlock;

// 訂閱'error', 'complete'事件
- (RACDisposable *)subscribeError:(void (^)(NSError * _Nullable error))errorBlock completed:(void (^)(void))completedBlock;

RACSignal(RACStream)

// 返回一個會立即發(fā)送給定value和complete的信號
// 方法內部調用RACReturnSignal類的return:方法
+ (RACSignal<ValueType> *)return:(nullable ValueType)value;

// 返回一個RACEmptySignal信號, 會立即發(fā)送complete的信號
+ (RACSignal<ValueType> *)empty; 

// 只改變當前流對象
// 將block懶綁定到接受者的值
// 只有在需要提前終止綁定或關閉某個狀態(tài)時才應該使用此選項。 -flattenMap:更適合所有其他情況宙暇。
// 參數(shù)block: 返回RACSignalBindBlock的block输枯。 每次重新評估綁定信號時,都會調用此block占贫。 此block不能為nil或返回nil桃熄。
// 返回值: 返回一個新信號,表示所有`block`的惰性應用的組合結果靶剑。
- (RACSignal *)bind:(RACSignalBindBlock (^)(void))block;

// 在當前響應流已經(jīng)完成后蜻拨,緊接著注入新的響應流
// 當源信號完成時,訂閱“signal”桩引。
- (RACSignal *)concat:(RACSignal *)signal;

// 是將不同的流進行打包合成一個流
// 使用給定信號的值將接收器中的值壓縮以創(chuàng)建RACTuples。
// 每個信號的第一個“next”將被組合收夸,然后是第二個“next”坑匠,依此類推,直到信號完成或出現(xiàn)錯誤卧惜。
// 參數(shù)signal: 要壓縮的信號厘灼,不能為nil
// 返回值: 返回RACTuples的新信號,表示兩個信號的組合值咽瓷。 其中一個原始信號的任何錯誤都將在返回的信號上轉發(fā)设凹。
- (RACSignal<RACTwoTuple<ValueType, id> *> *)zipWith:(RACSignal *)signal;

RACSignal(RACStreamOperations)

// 封裝bind操作, 將多個流的值映射到接受者上并生成一個新的流
// 將“block”映射到接收器中的值并使結果變平。
// 請注意茅姜,在-flattenMap之后應用的運算符與-flattenMap:中的運算符的行為不同闪朱。 請參閱下面的示例部分。
// 這對應于Rx中的`SelectMany`方法钻洒。
// 參數(shù)block: 一個block奋姿,它接受接收器中的值并返回接收器類的新實例。 從該block返回“nil”等同于返回空信號素标。
// 實例:
///   [signal flattenMap:^(id x) {
///       // 每次返回的信號完成時記錄称诗。
///       return [[RACSignal return:x] logCompleted];
///   }];
///
///   [[signal
///       flattenMap:^(id x) {
///           return [RACSignal return:x];
///       }]
///       // 所有信號完成后,只記錄一次头遭。
///       logCompleted];
// 返回一個新信號寓免,表示映射`block`產(chǎn)生的組合信號。
- (RACSignal *)flattenMap:(__kindof RACSignal * _Nullable (^)(ValueType _Nullable value))block;

// 將多個流拼接為一個流
// 使組合信號變平计维。
// 對應于Rx中的`Merge`方法袜香。
// 返回由接收器獲得的組合信號組成的信號。
- (RACSignal *)flatten;

// 將一個流的值通過轉換享潜,映射形成一個新的流
// 這對應于Rx中的“Select”方法困鸥。
// 返回帶有映射值的新信號。
- (RACSignal *)map:(id _Nullable (^)(ValueType _Nullable value))block;

// 直接使用object替換當前流的值并生成一個新的流
// 為接收器中的每個值返回一個新信號,其中包含給定對象一次疾就。
- (RACSignal *)mapReplace:(nullable id)object;

// 使用block來驗證每個值,將驗證結果通過的值生成新的流
// 過濾掉未通過給定測試的接收器中的值澜术。
// 這對應于Rx中的`Where`方法。
// 返回僅包含通過的值的新信號猬腰。
- (RACSignal<ValueType> *)filter:(BOOL (^)(ValueType _Nullable value))block;

// 忽略和當前值一樣的對象鸟废,將之變?yōu)榭樟?// 過濾掉接收器中等于(通過-isEqual :)提供的值的值。
// 參數(shù)value: 該值可以是“nil”姑荷,在這種情況下它會忽略“nil”值盒延。
// 返回一個新信號,其中只包含不等于`value`的值鼠冕。
- (RACSignal<ValueType> *)ignore:(nullable ValueType)value;

// 將流中的RACTuple對象進行過濾添寺,返回特定的衍生出的一個值對象
// 解壓縮接收器中的每個RACTuple并將值映射到新值。
// 參數(shù)reduceBlock: 將每個RACTuple的值減少為一個值的block懈费。 它必須采用與要處理的元組元素數(shù)量一樣多的參數(shù)计露。 每個參數(shù)都是一個對象參數(shù)。 返回值必須是對象憎乙。 這個參數(shù)不能是nil票罐。
// 返回減少元組值的新信號。
- (RACSignal *)reduceEach:(RACReduceBlock)reduceBlock;

// 在當前流的值流出之前泞边,加入一個初始值
// 返回由`value`組成的信號该押,后跟接收器中的值。
- (RACSignal<ValueType> *)startWith:(nullable ValueType)value;

// 忽略當前流前n次的對象值阵谚,將之變?yōu)榭樟?// 跳過接收器中的第一個`skipCount`值蚕礼。
// 跳過第一個`skipCount`值后返回接收器。 如果`skipCount`大于信號中的值的數(shù)量椭蹄,則返回空信號闻牡。
- (RACSignal<ValueType> *)skip:(NSUInteger)skipCount;

// 只取當前流中的前n次對象值,之后將流變?yōu)榭眨ú皇强樟鳎?// 返回接收器中第一個`count`值的信號绳矩。 如果`count`大于或等于信號中的值的數(shù)量罩润,則返回等效于接收器的信號。
- (RACSignal<ValueType> *)take:(NSUInteger)count;

// 將多個流中的值包裝成一個RACTuple對象
// 壓縮給定信號中的值以創(chuàng)建RACTuples翼馆。
// 將組合每個信號的第一個值割以,然后組合第二個值,依此類推应媚,直到至少一個信號耗盡严沥。
// 參數(shù)signals: 要結合的信號。 如果此集合為空中姜,則返回的信號將為空消玄。
// 返回包含信號中壓縮值的RACTuples的新信號跟伏。
+ (RACSignal<RACTuple *> *)zip:(id<NSFastEnumeration>)signals;

// 使用+ zip:壓縮信號,然后使用-reduceEach將生成的元組減少為單個值:
// 參數(shù)signals: 要結合的信號翩瓜。 如果此集合為空受扳,則返回的信號將為空。
// 參數(shù)reduceBlock: 將所有信號的值減少為一個值的block兔跌。 它必須采用與給定信號數(shù)量一樣多的參數(shù)勘高。 每個參數(shù)都是一個對象參數(shù)。 返回值必須是對象坟桅。 這個參數(shù)不能是nil华望。
// 實例: 
///   [RACSignal zip:@[ stringSignal, intSignal ]
///       reduce:^(NSString *string, NSNumber *number) {
///           return [NSString stringWithFormat:@"%@: %@", string, number];
///       }];
// 返回一個新信號,其中包含每次調用`reduceBlock`的結果仅乓。
+ (RACSignal<ValueType> *)zip:(id<NSFastEnumeration>)signals reduce:(RACGenericReduceBlock)reduceBlock;

// 將新的流拼接到接受者后面
// 返回通過按順序連接`signals`獲得的信號
+ (RACSignal<ValueType> *)concat:(id<NSFastEnumeration>)signals;

// 使用給定的block從左到右組合接收器中的值赖舟。
// 算法如下:
// 1. `startingValue`作為`running`值傳遞給block,接收器的第一個元素作為`next`值傳遞給block夸楣。
// 2. 調用的結果將添加到返回的信號中
// 3. 調用(`running`)的結果和接收器的下一個元素(`next`)被傳遞給`block`建蹄。
// 重復步驟2和3,直到處理完所有值裕偿。
// 參數(shù)startingValue: 要與接收器的第一個元素組合的值。 該值可能是“nil”痛单。
// 參數(shù)reduceBlock: 描述如何組合接收器值的block嘿棘。 如果接收方為空,則永遠不會調用此block旭绒。 不能是nil鸟妙。
// 實例:
///
///      RACSequence *numbers = @[ @1, @2, @3, @4 ].rac_sequence;
///
///      // Contains 1, 3, 6, 10
///      RACSequence *sums = [numbers scanWithStart:@0 reduce:^(NSNumber *sum, NSNumber *next) {
///          return @(sum.integerValue + next.integerValue);
///      }];
// 返回一個由`reduceBlock`的每個應用程序組成的新信號。 如果接收器為空挥吵,則返回空信號重父。
- (RACSignal *)scanWithStart:(nullable id)startingValue reduce:(id _Nullable (^)(id _Nullable running, ValueType _Nullable next))reduceBlock;

// 用同樣的block執(zhí)行每次流中的值,并將結果用于后一次執(zhí)行當中忽匈,每次都把block執(zhí)行后的值變成新的流中的對象
// 使用給定的block從左到右組合接收器中的值房午,該block也采用從零開始的值索引。
// 參數(shù)startingValue: 要與接收器的第一個元素組合的值丹允。 該值可能是“nil”郭厌。
// 參數(shù)reduceBlock: 描述如何組合接收器值的block。 此block將從零開始的索引值作為最后一個參數(shù)雕蔽。 如果接收方為空折柠,則永遠不會調用此block。 不可能是nil批狐。
// 返回一個由`reduceBlock`的每個應用程序組成的新信號扇售。 如果接收器為空,則返回空信號。
- (RACSignal *)scanWithStart:(nullable id)startingValue reduceWithIndex:(id _Nullable (^)(id _Nullable running, ValueType _Nullable next, NSUInteger index))reduceBlock;

// 將每個先前值和當前值組合到一個對象中承冰。
// 此方法類似于-scanWithStart:reduce:华弓,但只對前一個和當前值(而不是整個信號)進行操作,并且不會將`reduceBlock`的返回值傳遞給它的下一個調用巷懈。
// 參數(shù)start: 對于第一個值该抒,該值作為`previous`傳遞給`reduceBlock`。
// 參數(shù)reduceBlock: 將先前值和當前值組合在一起以創(chuàng)建減少值的block顶燕。 不能是nil凑保。
// 實例
///      RACSignal<NSNumber *> *numbers = [@[ @1, @2, @3, @4 ].rac_sequence
///          signalWithScheduler:RACScheduler.immediateScheduler];
///
///      // Contains 1, 3, 5, 7
///      RACSignal *sums = [numbers combinePreviousWithStart:@0 reduce:^(NSNumber *previous, NSNumber *next) {
///          return @(previous.integerValue + next.integerValue);
///      }];
// 返回一個新信號,該信號由`reduceBlock`的每個應用程序的返回值組成涌攻。
- (RACSignal *)combinePreviousWithStart:(nullable ValueType)start reduce:(id _Nullable (^)(ValueType _Nullable previous, ValueType _Nullable current))reduceBlock;

// 取當前流的對象值欧引,直到當前值滿足提供的block,就會將當前流變?yōu)榭眨ú皇强樟鳎?// 取值直到給定的block返回“YES”恳谎。
// 返回接收器中未通過`predicate`的初始值的信號芝此。 如果`predicate`永遠不會返回“YES”,則返回與接收器等效的信號因痛。
- (RACSignal<ValueType> *)takeUntilBlock:(BOOL (^)(ValueType _Nullable x))predicate;

// 取當前流的對象值婚苹,直到當前值不滿足提供的block,就會將當前流變?yōu)榭眨ú皇强樟鳎?// 取值直到給定的block返回“NO”鸵膏。
// 返回接收器中通過`predicate`的初始值的信號膊升。 如果`predicate`永遠不會返回`NO`,則返回等同于接收器的信號谭企。
- (RACSignal<ValueType> *)takeWhileBlock:(BOOL (^)(ValueType _Nullable x))predicate;

// 忽略當前流的對象值(變?yōu)榭樟鳎├耄钡疆斍爸禎M足提供的block。
// 跳過值债查,直到給定block返回“YES”非区。
// 返回一個信號,其中包含接收器的值盹廷,這些值遵循任何初始值未通過`predicate`征绸。 如果`predicate`永遠不會返回`YES`,則返回一個空信號速和。
- (RACSignal<ValueType> *)skipUntilBlock:(BOOL (^)(ValueType _Nullable x))predicate;

// 忽略當前流的對象值(變?yōu)榭樟鳎┐醯妫钡疆斍爸挡粷M足提供的block
// 跳過值,直到給定block返回“NO”颠放。
// 返回一個信號排惨,其中包含接收器的值,這些值遵循任何初始值通過`predicate`碰凶。 如果`predicate`永遠不會返回`NO`暮芭,則返回一個空信號鹿驼。
- (RACSignal<ValueType> *)skipWhileBlock:(BOOL (^)(ValueType _Nullable x))predicate;

// 當流中后一次的值和前一次的值不同的時候,才會返回當前值的流辕宏,否則返回空流(第一次默認被忽略)
// 返回值的信號 - -isEqual:與前一個值比較時返回NO畜晰。
- (RACSignal<ValueType> *)distinctUntilChanged;

RACSignal(Operations)


// 在`next`上執(zhí)行給定的block。 這應該用于將side effects(副作用)注入信號瑞筐。
- (RACSignal<ValueType> *)doNext:(void (^)(ValueType _Nullable x))block;

// 在`error`上執(zhí)行給定的block凄鼻。 這應該用于將side effects(副作用)注入信號。
- (RACSignal<ValueType> *)doError:(void (^)(NSError * _Nonnull error))block;

// 在`completed`上執(zhí)行給定的block聚假。 這應該用于將side effects(副作用)注入信號块蚌。
- (RACSignal<ValueType> *)doCompleted:(void (^)(void))block;

// 只有當在`interval`秒內沒有收到另一個`next`時才發(fā)送`next`s。
// 如果接收到“next”膘格,然后在“interval”秒之前接收到另一個“next”峭范,則丟棄第一個值.
// 在自最近的`next`被發(fā)送以來已經(jīng)過了`interval`秒之后,最新的`next`在調度程序上被轉發(fā)瘪贱,該值最初被接收纱控。 如果當時+ [RACScheduler currentScheduler]為nil,則使用私有后臺調度程序菜秦。
// 返回發(fā)送限制和延遲的“next”事件的信號甜害。 始終會立即轉發(fā)完成和錯誤。
- (RACSignal<ValueType> *)throttle:(NSTimeInterval)interval;

// 當predicate返回YES時節(jié)流'next'
// 當predicate為'next'返回YES時:
// 1. 如果在“interval”秒之前接收到另一個“next”球昨,則丟棄先前值唾那。 無論新值是否受到限制,都會發(fā)生這種情況褪尝。
// 2. 自最初收到值之后經(jīng)過`interval`秒后,它將在收到它的調度程序上轉發(fā)期犬。 如果當時+ [RACScheduler currentScheduler]為nil河哑,則使用私有后臺調度程序。
// 當`predicate`為`next`返回NO時龟虎,它立即被轉發(fā)璃谨,沒有任何限制。
// 參數(shù)interval: 緩沖傳遞`predicate`的最新值的秒數(shù)鲤妥。
// 參數(shù)predicate: 從接收器傳遞每個`next`佳吞,該block返回是否應該限制給定值。 這個參數(shù)不能是nil棉安。
// 返回發(fā)送`next`事件的信號底扳,當`predicate`返回YES時受到限制。 始終會立即轉發(fā)完成和錯誤贡耽。
- (RACSignal<ValueType> *)throttle:(NSTimeInterval)interval valuesPassingTest:(BOOL (^)(id _Nullable next))predicate;

// 在當前調度程序(事件已發(fā)送到其上)上延遲“interval”秒后衷模,轉發(fā)`next`和`completed`事件鹊汛。
// 如果收到“next”或“completed”時+ [RACScheduler currentScheduler]為nil,則使用私有后臺調度程序阱冶。
// 返回發(fā)送延遲的`next`和`completed`事件的信號刁憋。 錯誤總是立即轉發(fā)。
- (RACSignal<ValueType> *)delay:(NSTimeInterval)interval;

// 信號完成時重新訂閱木蹬。
- (RACSignal<ValueType> *)repeat;

// 每次創(chuàng)建訂閱時執(zhí)行給定的塊至耻。
// 參數(shù)block: 定義訂閱side effects的block。 不能是'nil`镊叁。
// 實例:
///   // 編寫新文件尘颓,備份。
///   [[[[fileManager
///       rac_createFileAtPath:path contents:data]
///       initially:^{
///           // 2. 二意系,備份當前文件
///           [fileManager moveItemAtPath:path toPath:backupPath error:nil];
///       }]
///       initially:^{
///           // 1. 首先泥耀,給writeLock加鎖。
///           [writeLock lock];
///       }]
///       finally:^{
///           [writeLock unlock];
///       }];
// 返回通過接收器的所有事件的信號蛔添,并引入在接收器的任何訂閱side effects之前發(fā)生的side effects痰催。
- (RACSignal<ValueType> *)initially:(void (^)(void))block;

// 信號完成或錯誤時執(zhí)行給定的block。
- (RACSignal<ValueType> *)finally:(void (^)(void))block;

// 將接收器的'next'分成緩沖區(qū)迎瞧,每個緩沖區(qū)提供每個'interval'秒夸溶。
// 參數(shù)interval: 值被分組到一個緩沖區(qū)的時間間隔
// 參數(shù)scheduler: 返回信號將在其上傳遞其值的調度程序。 不能是nil或+ [RACScheduler immediateScheduler]凶硅。
// 返回一個信號缝裁,該信號在`scheduler`上的每個間隔發(fā)送緩沖值的RACTuples。 當接收器完成時足绅,將立即發(fā)送任何當前緩沖的值捷绑。
- (RACSignal<RACTuple *> *)bufferWithTime:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler;

// 將所有接收者的'next'收集到NSArray中。 Nil值將轉換為NSNull氢妈。
// 這對應于Rx中的`ToArray`方法粹污。
// 返回當接收器成功完成時發(fā)送單個NSArray的信號。
- (RACSignal<NSArray<ValueType> *> *)collect;

// 在接收信號完成后接受最后一次`count`'next's首量。
- (RACSignal<ValueType> *)takeLast:(NSUInteger)count;

// 一旦兩者都發(fā)送了至少一個`next`壮吩,將接收器和給定信號的最新值組合成2元組。
// 任何額外的`next`s將導致一個新的RACTuple加缘,其中包含兩個信號的最新值鸭叙。
// 參數(shù)signal: 與之相結合的信號。 這個參數(shù)不能是nil拣宏。
// 返回發(fā)送組合值的RACTuples的信號沈贝,轉發(fā)任何“錯誤”事件,并在兩個輸入信號完成時完成勋乾。
- (RACSignal<RACTwoTuple<ValueType, id> *> *)combineLatestWith:(RACSignal *)signal;

// 一旦所有信號都發(fā)送了至少一個`next`缀程,就將給定信號的最新值合并到RACTuples中搜吧。
// 任何額外的`next`s將導致一個新的RACTuple,其中包含所有信號的最新值杨凑。
// 參數(shù)signals: 與之相結合的信號滤奈。如果此集合為空,則返回的信號將在訂閱后立即完成撩满。
// 返回發(fā)送組合值的RACTuples的信號蜒程,轉發(fā)任何“錯誤”事件,并在所有輸入信號完成時完成伺帘。
+ (RACSignal<RACTuple *> *)combineLatest:(id<NSFastEnumeration>)signals;

// 使用+ combineLatest:組合信號昭躺,然后使用-reduceEach:將生成的元組減少為單個值。
// 參數(shù)signals: 與之相結合的信號伪嫁。如果此集合為空领炫,則返回的信號將在訂閱后立即完成。
// 參數(shù)reduceBlock: 將所有信號中的最新值減少為一個值的block张咳。 它必須采用與給定信號數(shù)量一樣多的參數(shù)帝洪。 每個參數(shù)都是一個對象參數(shù)。 返回值必須是對象脚猾。 這個參數(shù)不能是nil葱峡。
// 實例:
///   [RACSignal combineLatest:@[ stringSignal, intSignal ] reduce:^(NSString *string, NSNumber *number) {
///       return [NSString stringWithFormat:@"%@: %@", string, number];
///   }];
// 返回一個信號,該信號發(fā)送每次調用`reduceBlock`的結果龙助。
+ (RACSignal<ValueType> *)combineLatest:(id<NSFastEnumeration>)signals reduce:(RACGenericReduceBlock)reduceBlock;

// 用`+ merge:`合并接收器和給定信號并返回結果信號砰奕。
- (RACSignal *)merge:(RACSignal *)signal;

// 從任何信號發(fā)送最新的`next`。
// 返回一個信號提鸟,該信號通過每個給定信號的值军援,并在所有信號完成時發(fā)送`completed`。 如果任何信號發(fā)送錯誤称勋,則返回的信號立即發(fā)送“錯誤”盖溺。
+ (RACSignal<ValueType> *)merge:(id<NSFastEnumeration>)signals;

// 將接收器發(fā)送的信號合并為扁平信號,但一次只能訂閱“maxConcurrent”數(shù)量的信號铣缠。 當其他信號完成時,新信號排隊并訂閱昆禽。
// 如果任何信號發(fā)生錯誤蝗蛙,則在返回的信號上發(fā)送。 它僅在接收器和所有發(fā)送信號完成后才完成醉鳖。
// 參數(shù)maxConcurrent:一次訂閱的最大信號數(shù)捡硅。 如果為0,則訂閱無限數(shù)量的信號盗棵。
- (RACSignal *)flatten:(NSUInteger)maxConcurrent;

// 忽略接收器中的所有`next`s壮韭,等待接收器完成北发,然后訂閱新信號呈础。
// 參數(shù)block: 將創(chuàng)建或獲取要訂閱的新信號的block住闯,僅在接收器完成后執(zhí)行考余。 該block不能為nil童谒,并且不能返回nil信號巨税。
// 返回一個信號谆刨,該信號將通過`block`中創(chuàng)建的信號事件渺鹦。 如果接收器出錯舀透,返回的信號也會出錯恶耽。
- (RACSignal *)then:(RACSignal * (^)(void))block;

// 匯總信號組的內部信號密任。
- (RACSignal *)concat;

// 將接收器的“next”值聚合為單個組合值。
// 算法如下:
// 1. `start`作為`running`值傳遞給block偷俭,接收器的第一個元素作為`next`值傳遞給block浪讳。
// 2. 調用(`running`)的結果和接收器的下一個元素(`next`)被傳遞到`reduceBlock`。
// 3. 重復步驟2和3涌萤,直到處理完所有值淹遵。
// 4. `reduceBlock`的最后一個結果是在返回的信號上發(fā)送的。
// 此方法類似于-scanWithStart:reduce:形葬,只是在返回的信號上僅發(fā)送最終結果合呐。
// 參數(shù)start:要與接收器的第一個元素組合的值。 該值可能是“nil”笙以。
// 參數(shù)reduceBlock: 描述如何組合接收器值的block淌实。 如果接收方為空,則永遠不會調用此塊猖腕。 不能是nil拆祈。
// 返回一個信號,該信號將在接收器完成時發(fā)送聚合值倘感,然后自行完成放坏。 如果接收方從不發(fā)送任何值,則會發(fā)送“start”老玛。
- (RACSignal *)aggregateWithStart:(id)start reduce:(id (^)(id running, id next))reduceBlock;

// 將接收器的“next”值聚合為單個組合值淤年。 這是-aggregateWithStart:reduce:的索引版本。
// 參數(shù)start:要與接收器的第一個元素組合的值蜡豹。 該值可能是“nil”麸粮。
// 參數(shù)reduceBlock: 描述如何組合接收器值的block。 此block將從零開始的索引值作為最后一個參數(shù)镜廉。 如果接收方為空弄诲,則永遠不會調用此block。 不能是nil娇唯。
// 返回一個信號齐遵,該信號將在接收器完成時發(fā)送聚合值寂玲,然后自行完成。 如果接收方從不發(fā)送任何值梗摇,則會發(fā)送“start”拓哟。
- (RACSignal *)aggregateWithStart:(id)start reduceWithIndex:(id (^)(id running, id next, NSUInteger index))reduceBlock;

// 將接收器的“next”值聚合為單個組合值。
// 這會在每個訂閱上調用`startFactory`block留美,然后調用-aggregateWithStart:reduce:將block的返回值作為起始值彰檬。
// 參數(shù)startFactory: 返回將與接收器的第一個元素組合的起始值的block。 不能是nil谎砾。
// 參數(shù)reduceBlock: 描述如何組合接收器值的block逢倍。 如果接收方為空,則永遠不會調用此block景图。 不能是nil较雕。
// 返回一個信號,該信號將在接收器完成時發(fā)送聚合值挚币,然后自行完成亮蒋。 如果接收器從不發(fā)送任何值,則將發(fā)送`startFactory`的返回值妆毕。
- (RACSignal *)aggregateWithStartFactory:(id (^)(void))startFactory reduce:(id (^)(id running, id next))reduceBlock;

// 每隔“interval”秒發(fā)送NSDate.date慎玖。
// 參數(shù)interval: 發(fā)送當前時間的時間間隔(以秒為單位)。
// 參數(shù)scheduler: 應在其上發(fā)送當前NSDate的調度程序笛粘。 這不能是nil或+ [RACScheduler immediateScheduler]趁怔。
// 返回一個信號,該信號在`scheduler`上每隔“interval”發(fā)送當前日期/時間薪前。
+ (RACSignal<NSDate *> *)interval:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler;

// 以至少`interval`秒的間隔發(fā)送NSDate.date润努,直到大約`interval` +`leeway`秒。
// 創(chuàng)建的信號將推遲發(fā)送每個“next”至少“interval”秒示括,并為了性能或功耗而延遲額外的“l(fā)eeway”秒铺浇。 請注意,即使指定“余地”為0垛膝,也可以預期一些額外的延遲鳍侣。
// 參數(shù)interval: ``next`s之間的基礎間隔。
// 參數(shù)scheduler: 應在其上發(fā)送當前NSDate的調度程序吼拥。 這不能是nil或+ [RACScheduler immediateScheduler].
// 參數(shù)leeway: “next”可以延遲的最大額外時間倚聚。
// 返回一個信號,該信號以至少“interval seconds”的間隔發(fā)送當前日期/時間扔罪,直到`scheduler`上的大約`interval` +`leeway`秒。
+ (RACSignal<NSDate *> *)interval:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler withLeeway:(NSTimeInterval)leeway;

// 采取`next`s直到`signalTrigger`發(fā)送`next`或`completed`桶雀。
// 返回一個信號矿酵,該信號從接收器傳遞所有事件唬复,直到`signalTrigger`發(fā)送`next`或`completed`,此時返回的信號將發(fā)送`completed`全肮。
- (RACSignal<ValueType> *)takeUntil:(RACSignal *)signalTrigger;

// 采取`next`s直到`replacement`發(fā)送事件敞咧。 
// 參數(shù)replacement: 一旦發(fā)送事件就會替換接收器的信號。
// 返回一個信號辜腺,它從接收器傳遞`next`s和`error`直到`replacement`發(fā)送一個事件休建,此時返回的信號將發(fā)送該事件并切換到來自`replacement`的事件,而不管是否 接收者已經(jīng)發(fā)送了事件评疗。
- (RACSignal *)takeUntilReplacement:(RACSignal *)replacement;

// 發(fā)生錯誤時訂閱返回的信號测砂。
- (RACSignal *)catch:(RACSignal * (^)(NSError * _Nonnull error))catchBlock;

// 發(fā)生錯誤時訂閱給定信號。
- (RACSignal *)catchTo:(RACSignal *)signal;

// 返回一個信號百匆,該信號將立即發(fā)送`tryBlock`的返回值并完成砌些,或使用從block傳出的`NSError`發(fā)生錯誤。
// 參數(shù)tryBlock: 執(zhí)行某些可能失敗的計算的操作加匈。 如果block返回nil存璃,則block必須通過`errorPtr`參數(shù)返回錯誤。
// 實例:
///   [RACSignal try:^(NSError **error) {
///       return [NSJSONSerialization JSONObjectWithData:someJSONData options:0 error:error];
///   }];
+ (RACSignal<ValueType> *)try:(nullable ValueType (^)(NSError **errorPtr))tryBlock;

// 對每個接收者的值運行`tryBlock`雕拼,傳遞值直到`tryBlock`返回NO纵东,或接收者完成。
// 參數(shù)tryBlock: 針對每個接收者值運行的操作啥寇。 該block應返回YES以指示操作成功偎球。 此block不能為nil。
// 實例:
///   // 如果無法將數(shù)據(jù)值寫入`someFileURL`示姿,則返回的信號將發(fā)送錯誤甜橱。
///   [signal try:^(NSData *data, NSError **errorPtr) {
///       return [data writeToURL:someFileURL options:NSDataWritingAtomic error:errorPtr];
///   }];
// 返回一個通過接收器所有值的信號。 如果`tryBlock`對任何值都失敗栈戳,則返回的信號將使用從block傳出的`NSError`錯誤岂傲。
- (RACSignal<ValueType> *)try:(BOOL (^)(id _Nullable value, NSError **errorPtr))tryBlock;

// 對每個接收者的值運行`mapBlock`,映射值直到`mapBlock`返回nil子檀,或者接收者完成镊掖。
// 參數(shù)mapBlock: 映射每個接收者值的動作。 該block應返回非空值以指示操作成功褂痰。 此block不能為nil亩进。
// 實例
///     // 如果無法從`fileURL`讀取數(shù)據(jù),則返回的信號將發(fā)送錯誤缩歪。
///   [signal tryMap:^(NSURL *fileURL, NSError **errorPtr) {
///       return [NSData dataWithContentsOfURL:fileURL options:0 error:errorPtr];
///   }];
// 返回一個轉換接收器所有值的信號归薛。 如果`mapBlock`為任何值返回nil,則返回的信號將使用從block傳出的`NSError`錯誤。
- (RACSignal *)tryMap:(id (^)(id _Nullable value, NSError **errorPtr))mapBlock;

// 返回第一個`next`主籍。 請注意习贫,這是一個阻止調用。
- (nullable ValueType)first;

// 如果信號完成則返回第一個`next`或`defaultValue`或返回錯誤而不發(fā)送`next`千元。 請注意苫昌,這是一個阻止調用。
- (nullable ValueType)firstOrDefault:(nullable ValueType)defaultValue;

// 如果信號完成則返回第一個`next`或`defaultValue`或返回錯誤而不發(fā)送`next`幸海。 如果發(fā)生錯誤祟身,則成功將為NO并且將填充錯誤。 請注意物独,這是一個阻止調用袜硫。
// 成功和錯誤都可能為NULL。
- (nullable ValueType)firstOrDefault:(nullable ValueType)defaultValue success:(nullable BOOL *)success error:(NSError * _Nullable * _Nullable)error;

// 阻止調用者并等待信號完成议纯。
// 參數(shù)error: 如果不為NULL父款,則設置為發(fā)生的任何錯誤。
// 返回信號是否成功完成瞻凤。 如果為NO憨攒,則將“error”設置為發(fā)生的錯誤。
- (BOOL)waitUntilCompleted:(NSError * _Nullable * _Nullable)error;

// 延遲信號的創(chuàng)建阀参,直到信號實際訂閱為止肝集。
// 這可用于有效地將熱信號轉換為冷信號。
+ (RACSignal<ValueType> *)defer:(RACSignal<ValueType> * (^)(void))block;

// 每次接收器發(fā)送一個新的RACSignal時蛛壳,只為該信號訂閱并發(fā)送`next`s和'error`s杏瞻。
// 接收器必須是信號組的一個信號。
// 返回一個信號衙荐,該信號從接收器發(fā)送的最新信號中通過`next`s和'error`s捞挥,并在接收器和最后發(fā)送的信號都完成時發(fā)送`completed`。
- (RACSignal *)switchToLatest;

// 根據(jù)`signal`發(fā)送的最新值忧吟,在`cases`和`defaultSignal`之間切換信號砌函。
// 參數(shù)signal:在`cases`字典中用作鍵的對象的信號。 這個參數(shù)不能是nil溜族。
// 參數(shù)cases: 具有信號值的字典讹俊。 這個參數(shù)不能是nil。 此字典中的RACTupleNil鍵將匹配在`signal`上接收的nil`next`事件煌抒。
// 參數(shù)defaultSignal: 在`signal`之后傳遞的信號發(fā)送一個`cases`不包含信號的值仍劈。 如果為nil,則任何不匹配的值都將導致RACSignalErrorNoMatchingCase錯誤寡壮。
// 返回一個信號贩疙,它通過`case`或`defaultSignal`中的一個信號傳遞`next`s和`error`讹弯,并在`signal`和最后一個使用的信號完成時發(fā)送`completed`。 如果沒有給出`defaultSignal`这溅,則不匹配的`next`將導致返回信號出錯闸婴。
+ (RACSignal<ValueType> *)switch:(RACSignal *)signal cases:(NSDictionary *)cases default:(nullable RACSignal *)defaultSignal;

// 根據(jù)`boolSignal`發(fā)送的最新值在`trueSignal`和`falseSignal`之間切換。
// 參數(shù)boolSignal: 確定“trueSignal”或“falseSignal”是否應該激活的BOOL信號芍躏。 這個參數(shù)不能是nil。
// 參數(shù)trueSignal: 在'boolSignal`發(fā)送YES后要通過的信號降狠。 這個參數(shù)不能是nil对竣。
// 參數(shù)falseSignal: 在'boolSignal`發(fā)送NO后要通過的信號。 這個參數(shù)不能是nil榜配。
// 返回一個信號否纬,該信號從`trueSignal`和/或`falseSignal`傳遞`next`s和`error`s,并在'boolSignal`和最后一個切換信號完成時發(fā)送`completed`蛋褥。
+ (RACSignal<ValueType> *)if:(RACSignal<NSNumber *> *)boolSignal then:(RACSignal *)trueSignal else:(RACSignal *)falseSignal;

// 將每個`next`添加到數(shù)組中临燃。 Nils由NSNulls代表。 請注意烙心,這是一個阻止調用膜廊。
// 返回`next`值的數(shù)組,如果發(fā)生錯誤淫茵,則返回nil爪瓜。
- (nullable NSArray<ValueType> *)toArray;

// 將每個`next`添加到序列中。 Nils由NSNulls代表匙瘪。
// 返回一個序列铆铆,在發(fā)送信號時提供信號的值。 嘗試從尚未發(fā)送的序列中檢索值將阻止丹喻。
@property (nonatomic, strong, readonly) RACSequence<ValueType> *sequence;;

// 創(chuàng)建并返回多播連接薄货。 這允許您共享對基礎信號的單個訂閱。
- (RACMulticastConnection<ValueType> *)publish;

// 創(chuàng)建并返回將值推送到給定subject的多播連接碍论。 這允許您共享對基礎信號的單個訂閱谅猾。
- (RACMulticastConnection<ValueType> *)multicast:(RACSubject<ValueType> *)subject;

// 將信號多播到無限容量的RACReplaySubject,并立即連接到生成的RACMulticastConnection骑冗。
// 返回連接的多播信號赊瞬。
- (RACSignal<ValueType> *)replay;

// 將信號多播到容量為1的RACReplaySubject,并立即連接到生成的RACMulticastConnection贼涩。
// 返回連接的多播信號巧涧。
- (RACSignal<ValueType> *)replayLast;

// 將信號多播到無限容量的RACReplaySubject,并且延遲地連接到生成的RACMulticastConnection遥倦。
// 這意味著只有當前者收到第一個訂閱時谤绳,返回的信號才會訂閱多播信號占锯。
// 返回延遲連接的多播信號。
- (RACSignal<ValueType> *)replayLazily;

// 如果在此之前源未完成缩筛,則在“interval”秒后發(fā)送錯誤消略。
// 錯誤將在RACSignalErrorDomain中,并且代碼為RACSignalErrorTimedOut瞎抛。
// 參數(shù)interval: 信號出錯之前的秒數(shù)艺演。
// 參數(shù)scheduler: 應該發(fā)送任何超時錯誤的調度程序。 這不能是nil或+ [RACScheduler immediateScheduler]桐臊。
// 返回通過接收者事件的信號胎撤,直到流完成或超時,此時將在`scheduler`上發(fā)送錯誤断凶。
- (RACSignal<ValueType> *)timeout:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler;

// 創(chuàng)建并返回在給定調度程序上傳遞其事件的信號伤提。 接收器的任何side effects仍將在原始線程上執(zhí)行。
// 當信號已經(jīng)在所需的線程上執(zhí)行其工作认烁,但您希望在其他地方處理其事件時肿男,這是理想的。
- (RACSignal<ValueType> *)deliverOn:(RACScheduler *)scheduler;

// 創(chuàng)建并返回執(zhí)行其side effects的信號却嗡,并在給定的調度程序上傳遞其事件舶沛。
// 應盡可能避免使用此運算符,因為接收器的side effects在另一個線程上運行可能不安全窗价。 如果您只想在`scheduler`上接收信號的事件冠王,請使用-deliverOn:代替。
- (RACSignal<ValueType> *)subscribeOn:(RACScheduler *)scheduler;

// 創(chuàng)建并返回在主線程上傳遞其事件的信號舌镶。 如果事件已經(jīng)在主線程上發(fā)送柱彻,則可以毫不拖延地傳遞它們。 如果在另一個線程上發(fā)送餐胀,或者如果先前的事件已在處理或已排隊哟楷,則事件將排隊等待以后在主線程上傳遞。
// 接收器的任何side effects仍將在原始線程上執(zhí)行否灾。
// 當信號將導致UI更新時卖擅,可以使用此方法,以避免由延遲傳遞事件(例如視圖實例化時RACObserve中的第一個事件)引起的潛在閃爍墨技。
- (RACSignal<ValueType> *)deliverOnMainThread;

// 將每個接收到的對象分組到一個組中惩阶,通過使用該對象調用“keyBlock”來確定。 通過使用對象調用`transformBlock`來轉換發(fā)送的對象扣汪。 如果`transformBlock`為nil断楷,則發(fā)送原始對象。
// 返回的信號是RACGroupedSignal的信號崭别。
- (RACSignal<RACGroupedSignal *> *)groupBy:(id<NSCopying> _Nullable (^)(id _Nullable object))keyBlock transform:(nullable id _Nullable (^)(id _Nullable object))transformBlock;

// 調用-[RACSignal groupBy:keyBlock transform:nil].
- (RACSignal<RACGroupedSignal *> *)groupBy:(id<NSCopying> _Nullable (^)(id _Nullable object))keyBlock;

// 如果接收信號發(fā)送任何對象冬筒,則發(fā)送[NSNumber numberWithBool:YES]恐锣。
- (RACSignal<NSNumber *> *)any;

// 如果接收信號發(fā)送任何通過`predicateBlock`的對象,則發(fā)送[NSNumber numberWithBool:YES]舞痰。
// 參數(shù)predicateBlock - 不能為nil.
- (RACSignal<NSNumber *> *)any:(BOOL (^)(id _Nullable object))predicateBlock;

// 如果接收信號發(fā)送的所有對象都通過`predicateBlock`土榴,則發(fā)送[NSNumber numberWithBool:YES]。
// 參數(shù)predicateBlock - 不能為nil.
- (RACSignal<NSNumber *> *)all:(BOOL (^)(id _Nullable object))predicateBlock;

// 如果發(fā)生錯誤响牛,則重新訂閱接收信號玷禽,直到重試給定次數(shù)為止。
// 參數(shù)retryCount: 如果為0呀打,它會一直重試论衍,直到完成。
- (RACSignal<ValueType> *)retry:(NSInteger)retryCount;

// 如果發(fā)生錯誤聚磺,則重新訂閱接收信號。
- (RACSignal<ValueType> *)retry;

// 僅當“sampler”發(fā)送值時才從接收器發(fā)送最新值炬丸。 如果`sampler`比接收器更頻繁地觸發(fā)瘫寝,則返回的信號可以重復值。 來自`sampler`的值在接收器發(fā)送其第一個值之前被忽略稠炬。
// 參數(shù)sampler: 控制何時發(fā)送來自接收器的最新值的信號焕阿。 不能為nil。
- (RACSignal<ValueType> *)sample:(RACSignal *)sampler;

// 忽略接收器中的所有‘next’首启。
// 返回僅從接收器傳遞“error”或“completed”事件的信號暮屡。
- (RACSignal *)ignoreValues;

// 將每個接收者的事件轉換為RACEvent對象。
// 返回一個信號毅桃,它將接收者的事件作為RACEvents發(fā)送褒纲,并在接收者發(fā)送“completed”或“error”后完成。
- (RACSignal<RACEvent<ValueType> *> *)materialize;

// 將接收器中的每個RACEvent轉換回“真正的”RACSignal事件钥飞。
// 返回一個信號莺掠,為每個值RACEvent發(fā)送`next`,為每個錯誤RACEvent發(fā)送`error`读宙,為每個完成的RACEvent發(fā)送`completed`彻秆。
- (RACSignal *)dematerialize;

// 反轉接收器發(fā)送的每個NSNumber包裝的BOOL。 如果接收者發(fā)送除NSNumbers之外的任何內容结闸,它將斷言唇兑。
// 返回反轉的NSNumber包裝的BOOL的信號。
- (RACSignal<NSNumber *> *)not;

// 在接收方發(fā)送的所有NSNumbers的RACTuple上執(zhí)行AND桦锄。
// 如果接收方發(fā)送除一個或多個NSNumber的RACTuple之外的任何內容扎附,則斷言。
// 返回一個信號结耀,該信號對元組中的每個NSNumber應用AND帕棉。
- (RACSignal<NSNumber *> *)and;

//在接收方發(fā)送的所有NSNumbers的RACTuple上執(zhí)行OR
// 如果接收方發(fā)送除一個或多個NSNumber的RACTuple之外的任何內容针肥,則斷言。
// 返回一個信號香伴,該信號對元組中的每個NSNumber應用OR慰枕。
- (RACSignal<NSNumber *> *)or;

// 使用接收器發(fā)送的每個RACTuple中打包的參數(shù)發(fā)送調用塊的結果。
// 接收器必須發(fā)送元組值即纲,其中元組的第一個元素是塊具帮,取多個參數(shù)等于元組的其余元素的計數(shù),并返回一個對象低斋。 每個塊必須至少有一個參數(shù)蜂厅,因此每個元組必須包含至少2個元素。
// 實例:
///   RACSignal *adder = [RACSignal return:^(NSNumber *a, NSNumber *b) {
///       return @(a.intValue + b.intValue);
///   }];
///   RACSignal *sums = [[RACSignal
///       combineLatest:@[ adder, as, bs ]]
///       reduceApply];
// 返回將每個元組的第一個元素應用于其余元素的結果的信號膊畴。
- (RACSignal *)reduceApply;

RACSubscriber

  • RACSubscriber.h 文件 -> RACSubscriber協(xié)議
  • RACSubscriber.m 文件 -> RACSubscriber類的擴展以及實現(xiàn)代碼
  • RACSubscriber+Private.h 文件 -> RACSubscriber類的頭文件

注意: RACSubscriber類 遵守 RACSubscriber協(xié)議

RACSubscriber協(xié)議四個必須實現(xiàn)的方法
- sendNext:
- sendError:
- sendCompleted
- didSubscribeWithDisposable:

// 給訂閱者subscribers發(fā)送next value
- (void)sendNext:(nullable id)value;

// 給訂閱者subscribers發(fā)送一個error
// 會立即終止subscription掘猿,并且使subscriber作廢, 也就是說subscriber將不能訂閱任何事情
- (void)sendError:(nullable NSError *)error;

// 給訂閱者subscribers發(fā)送completed
// 會立即終止subscription,并且使subscriber作廢, 也就是說subscriber將不能訂閱任何事情
- (void)sendCompleted;

// 給訂閱者subscriber發(fā)送一個disposable
- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)disposable;

RACSubscriber類遵守了RACSubscriber協(xié)議
RACSubscriber類

// 實例化方法
// 根據(jù)給定的next, error, completed參數(shù)創(chuàng)建一個subscriber
// 類的擴展中包含next, error, completed三個block屬性用于保存初始化時傳遞進來的三個參數(shù)唇跨,和一個只讀的disposable屬性稠通,初始化的時候回創(chuàng)建一個disposable(RACCompoundDisposable類)。
+ (instancetype)subscriberWithNext:(void (^)(id x))next error:(void (^)(NSError *error))error completed:(void (^)(void))completed;

// 協(xié)議方法的實現(xiàn)
// 調用保存的next這個block塊
- (void)sendNext:(id)value {...}

// 1. 調用self.disposable的dispose方法
// 2. 調用保存的error這個block塊
- (void)sendError:(NSError *)e {...}

// 1. 調用self.disposable的dispose方法
// 2. 調用保存的completed這個block塊
- (void)sendCompleted {...}

// 1. 給self.disposable添加一個otherDisposable
// 2. otherDisposable添加一個新創(chuàng)建的RACDisposable實例买猖,并在創(chuàng)建時的block中,將otherDisposable從self.disposable中移除改橘,避免內存無限增加。
- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)otherDisposable {...}

RACCommand

通常玉控,Command是響應某些動作而觸發(fā)的信號

屬性

// 成功調用-execute返回的信號的信號:(即接收者“啟用”時)飞主。
// 錯誤將自動捕獲內部信號,并在“errors”上發(fā)送高诺。 如果要接收內部錯誤碌识,請使用-execute:或 - [RACSignal materialize]。
// 只有在訂閱之后的執(zhí)行將根據(jù)此信號發(fā)送虱而。所有內部信號都將達到主線程
@property (nonatomic, strong, readonly) RACSignal<RACSignal<ValueType> *> *executionSignals;

// 發(fā)送這條命令是否正在執(zhí)行的信號
// 每當調用-execute:并且創(chuàng)建的信號尚未終止時丸冕,這將發(fā)送YES。 一旦所有執(zhí)行終止薛窥,`executing`將發(fā)送NO胖烛。
// 此信號將在訂閱時發(fā)送其當前值,然后在主線程上發(fā)送所有未來值诅迷。
@property (nonatomic, strong, readonly) RACSignal<NSNumber *> *executing;

// 發(fā)送這條命令是否能夠執(zhí)行的信號
// 出現(xiàn)以下情況時會發(fā)送NO:
// 1. 該命令是使用`enabledSignal`創(chuàng)建的佩番,并且在該信號上發(fā)送NO,
// 2. “allowsConcurrentExecution”為NO且命令已開始執(zhí)行罢杉。
// 一旦不再滿足上述條件趟畏,信號將發(fā)送YES。
// 此信號將在訂閱時發(fā)送其當前值滩租,然后在主線程上發(fā)送所有未來值赋秀。
@property (nonatomic, strong, readonly) RACSignal<NSNumber *> *enabled;

// 轉發(fā)-execute:返回的信號中發(fā)生的任何錯誤利朵。
// 當從-execute:返回的信號發(fā)生錯誤時稳懒,該信號將相關的NSError值作為“next”事件發(fā)送(因為`error`事件將終止該流)陆淀。
// 訂閱后,此信號將在主線程上發(fā)送所有未來錯誤腌闯。
@property (nonatomic, strong, readonly) RACSignal<NSError *> *errors;

// 這條命令是否允許多個執(zhí)行同時進行著洼。默認為NO
@property (atomic, assign) BOOL allowsConcurrentExecution;

方法

// 調用下面的方法樟遣,enabledSignal傳nil 
- (instancetype)initWithSignalBlock:(RACSignal<ValueType> * (^)(InputType _Nullable input))signalBlock;

// 根據(jù)條件初始化一個command
// 參數(shù):
// enabledSignal: BOOL值的信號,指示是否應該啟用命令身笤。 `enabled`將基于此信號發(fā)送的最新值豹悬。 在發(fā)送任何值之前,`enabled`將默認為YES液荸。 這個參數(shù)可能是nil瞻佛。
// signalBlock: 一個block,它將每個輸入值(傳遞給-execute :)映射到工作信號娇钱。 返回的信號將被多播到replay subject伤柄,在`executionSignals`上發(fā)送,然后同步訂閱忍弛。 block和返回的信號都不為nil。
- (instancetype)initWithEnabled:(nullable RACSignal<NSNumber *> *)enabledSignal signalBlock:(RACSignal<ValueType> * (^)(InputType _Nullable input))signalBlock;

// 如果接受者是enabled考抄,將:
// 1. 調用初始化時給出的signalBlock
// 2. 將返回的信號多播到RACReplaySubject细疚。
// 3. 在`executionSignals`上發(fā)送多播信號。
// 4. 訂閱(連接)主線程上的原始信號川梅。
// 
// 參數(shù)input: 傳遞給接收者的`signalBlock`的輸入值疯兼。 這可能是零
// 訂閱后返回多播信號。如果接受者不是enabled贫途,則返回一個發(fā)送代碼為RACCommandErrorNotEnabled錯誤的信號吧彪。
- (RACSignal<ValueType> *)execute:(nullable InputType)input;

RACDisposable

負責清除訂閱所需的工作

// 接收器是否已被丟棄。
// 不鼓勵使用此屬性丢早,因為它可以在任何時間同時設置為“是”
// 此屬性不符合KVO標準姨裸。
@property (atomic, assign, getter = isDisposed, readonly) BOOL disposed;

// 初始化
+ (instancetype)disposableWithBlock:(void (^)(void))block;

// 執(zhí)行清理工作。 可以多次調用怨酝,但后續(xù)調用不會執(zhí)行任何操作傀缩。
- (void)dispose;

// 返回一個新的Disposable,當它被銷毀時會丟棄农猬。
- (RACScopedDisposable *)asScopedDisposable;

RACSequence類

RACSequence

// 序列中的第一個對象赡艰,如果序列為空,則為nil斤葱。
// 子類必須提供此方法的實現(xiàn)慷垮。
@property (nonatomic, strong, readonly, nullable) ValueType head;

// 除序列中的第一個對象外的所有對象揖闸,如果沒有其他對象,則為nil料身。
// 子類必須提供此方法的實現(xiàn)汤纸。
@property (nonatomic, strong, readonly, nullable) RACSequence<ValueType> *tail;

// 評估完整序列以生成等效大小的數(shù)組。
@property (nonatomic, copy, readonly) NSArray<ValueType> *array;

// 返回序列中所有對象的枚舉器惯驼。
@property (nonatomic, copy, readonly) NSEnumerator<ValueType> *objectEnumerator;

// 將序列轉換為急切序列蹲嚣。
// 急切的序列會立即全面評估其所有值。 來自急切序列的序列也將非乘钌渴望隙畜。
// 返回一個新的急切序列,如果序列已經(jīng)急切说贝,則返回接收者议惰。
@property (nonatomic, copy, readonly) RACSequence<ValueType> *eagerSequence;

// 將序列轉換為延遲序列。
// 延遲序列在訪問它們時按需評估其值乡恕。 衍生自惰性序列的序列也是惰性的言询。
// 返回一個新的延遲序列,如果序列已經(jīng)是惰性的傲宜,則返回接收者运杭。
@property (nonatomic, copy, readonly) RACSequence<ValueType> *lazySequence;

// 使用新的RACScheduler調用-signalWithScheduler:。
- (RACSignal<ValueType> *)signal;

// 評估給定調度程序的完整序列函卒。
// 每個項目在其自己的調度塊中進行評估辆憔,以便在每個值之間產(chǎn)生對調度程序的控制。
// 返回一個信號报嵌,該信號在給定的調度程序進行評估時發(fā)送接收器的值虱咧。
- (RACSignal<ValueType> *)signalWithScheduler:(RACScheduler *)scheduler;

// 對序列應用左折疊。
// 這與迭代序列以及提供的起始值相同锚国。 這使用恒定的內存量腕巡。 左側折疊是左關聯(lián)的,因此在序列[1,2,3]中血筑,塊將按以下順序應用:reduce(reduce(reduce(start绘沉,1),2)豺总,3)
// 參數(shù)start: 折疊的起始值梆砸。 用作第一次折疊的“累加器”。
// 參數(shù)reduce: 用于組合累計值和下一個值的block园欣。不能為nil
// 返回減少的值
- (id)foldLeftWithStart:(nullable id)start reduce:(id _Nullable (^)(id _Nullable accumulator, ValueType _Nullable value))reduce;

// 對序列應用右折疊帖世。
// 右側折疊相當于列表中的遞歸。 該列從列表中的右側到左側進行評估。 它是右關聯(lián)的日矫,所以它首先應用于最右邊的元素赂弓。 例如,在序列[1,2,3]中哪轿,塊按以下順序應用:reduce(1盈魁,reduce(2,reduce(3窃诉,start)))
// 參數(shù)start: 折疊的起始值杨耙。
// 參數(shù)reduce: 用于組合累計值和下一個頭的塊。 該塊被賦予累積值和其余計算的值(遞歸的結果)飘痛。 使用`rest.head`檢索其值時計算珊膜。 如果您不需要,可以通過不訪問`rest.head`來防止不必要的計算宣脉。
// 返回減少的值
- (id)foldRightWithStart:(nullable id)start reduce:(id _Nullable (^)(id _Nullable first, RACSequence *rest))reduce;

// 檢查序列中的任何值是否通過block车柠。
// 參數(shù)block: block謂詞用于檢查每個項目,不能為nil塑猖。
// 返回一個布爾值竹祷,指示序列中是否傳遞了任何值
- (BOOL)any:(BOOL (^)(ValueType _Nullable value))block;

// 檢查序列中的所有值是否都通過了block。
// 參數(shù)block: block謂詞用于檢查每個項目羊苟,不能為nil塑陵。
// 返回一個布爾值,指示序列中是否傳遞了所有值
- (BOOL)all:(BOOL (^)(ValueType _Nullable value))block;

// 返回通過block的第一個對象蜡励。
// 參數(shù)block: block謂詞用于檢查每個項目令花,不能為nil。
// 如果有通過block則返回通過的第一個對象巍虫,如果沒有對象通過則返回nil 
- (nullable ValueType)objectPassingTest:(BOOL (^)(ValueType _Nullable value))block;

// 創(chuàng)建一個動態(tài)生成其值的序列彭则。
// 參數(shù)headBlock: 第一次調用-head被訪問鳍刷。
// 參數(shù)tailBlock: 第一次調用-tail被訪問占遥。
// 每個塊的結果都被記憶,因此無論訪問序列的頭部和尾部屬性多次输瓜,每個塊最多只會被調用一次瓦胎。
// `headBlock`或`tailBlock`中的任何side effects都應該是線程安全的,因為可以在任何時候從任何線程計算序列尤揣。 不僅如此搔啊,可以在-head之前訪問-tail,或者可以同時訪問兩者北戏。 如上所述负芋,side effects僅在第一次觸發(fā)-head或觸發(fā)-tail時觸發(fā)。
+ (RACSequence<ValueType> *)sequenceWithHeadBlock:(ValueType _Nullable (^)(void))headBlock tailBlock:(nullable RACSequence<ValueType> *(^)(void))tailBlock;

RACSequence(RACStream)

// 返回立即發(fā)送給定值然后完成的序列嗜愈。
+ (RACSequence<ValueType> *)return:(nullable ValueType)value;

// 返回立即完成的序列旧蛾。
+ (RACSequence<ValueType> *)empty;

// 一個block莽龟,它接受來自RACSequence的值并返回一個新序列。
// 將`stop`設置為`YES`將導致綁定在返回值后終止锨天。 返回“nil”將導致立即終止毯盈。
typedef RACSequence * _Nullable (^RACSequenceBindBlock)(ValueType _Nullable value, BOOL *stop);

// 延遲地將block綁定到接收器中的值。
// 只有在需要提前終止綁定或關閉某個狀態(tài)時才應該使用此選項病袄。 -flattenMap:更適合所有其他情況搂赋。
// 參數(shù)block: 返回RACSequenceBindBlock的block。 每次重新評估綁定序列時益缠,都會調用此block脑奠。 此塊不能為nil或返回nil。
// 返回一個新序列左刽,它表示`block`的所有惰性應用程序的組合結果捺信。
- (RACSequence *)bind:(RACSequenceBindBlock (^)(void))block;

// 源序列完成時訂閱`sequence`
- (RACSequence *)concat:(RACSequence *)sequence;

// 使用給定序列的值將接收器中的值壓縮以創(chuàng)建RACTuples。
// 每個序列的第一個“next”將被組合欠痴,然后是第二個“next”迄靠,依此類推,直到任一序列完成或錯誤喇辽。
// 參數(shù)sequence: 用來壓縮的序列掌挚,不能為nil
// 返回RACTuples的新序列,表示兩個序列的組合值菩咨。 原始序列之一的任何錯誤都將在返回的序列上轉發(fā)吠式。
- (RACSequence<RACTuple *> *)zipWith:(RACSequence *)sequence;

RACStream(RACStreamOperations)

// 將“block”映射到接收器中的值并使結果變平。
// 參數(shù)block: 一個block抽米,它接受接收器中的值并返回接收器類的新實例特占。 從這個block返回`nil`相當于返回一個空序列。
// 返回一個新序列云茸,表示映射`block`得到的組合序列是目。
- (RACSequence *)flattenMap:(__kindof RACSequence * _Nullable (^)(ValueType _Nullable value))block;

// 是組合序列變平
// 返回由從接收器獲得的組合序列組成的序列。
- (RACSequence *)flatten;

// 通過block來映射序列
// 返回帶有映射值的新序列
- (RACSequence *)map:(id _Nullable (^)(ValueType _Nullable value))block;

// 用給定對象替換接收器中的每個值标捺。
// 返回一個新序列懊纳,該序列包含接收器中每個值的給定對象一次。
- (RACSequence *)mapReplace:(nullable id)object;

// 過濾掉未通過給定測試的接收器中的值亡容。
// 返回僅包含通過的值的新序列嗤疯。
- (RACSequence<ValueType> *)filter:(BOOL (^)(id _Nullable value))block;

// 過濾掉接收器中等于(通過-isEqual :)提供的值的值。
// 返回一個新序列闺兢,僅包含不等于`value`的值茂缚。
- (RACSequence *)ignore:(nullable ValueType)value;

// 解壓縮接收器中的每個RACTuple并將值映射到新值。
// 參數(shù)reduceBlock: 將每個RACTuple的值減少為一個值的block。 它必須采用與要處理的元組元素數(shù)量一樣多的參數(shù)脚囊。 每個參數(shù)都是一個對象參數(shù)帖汞。 返回值必須是對象。 這個參數(shù)不能是nil凑术。
// 返回減少的元組值的新序列翩蘸。
- (RACSequence *)reduceEach:(RACReduceBlock)reduceBlock;

// 返回由`value`組成的序列,后跟接收器中的值淮逊。
- (RACSequence<ValueType> *)startWith:(nullable ValueType)value;

// 跳過接收器中的第一個`skipCount`值催首。
// 跳過第一個`skipCount`值后返回接收器。 如果`skipCount`大于序列中的值的數(shù)量泄鹏,則返回空序列郎任。
- (RACSequence<ValueType> *)skip:(NSUInteger)skipCount;

// 返回接收器中第一個`count`值的序列。 如果`count`大于或等于序列中的值的數(shù)量备籽,則返回等同于接收器的序列舶治。
- (RACSequence<ValueType> *)take:(NSUInteger)count;

// 壓縮給定序列中的值以創(chuàng)建RACTuples。
// 將組合每個序列的第一個值车猬,然后組合第二個值霉猛,依此類推,直到至少一個序列耗盡珠闰。
// 參數(shù)sequences: 要結合的序列惜浅。 如果此集合為空,則返回的序列將為空伏嗜。
// 返回包含序列中壓縮值的RACTuples的新序列坛悉。
+ (RACSequence<RACTuple *> *)zip:(id<NSFastEnumeration>)sequence;

// 使用+ zip:壓縮序列,然后使用-reduceEach:將生成的元組減少為單個值承绸。
// 參數(shù)sequences: 要結合的序列裸影。 如果此集合為空,則返回的序列將為空军熏。
// 參數(shù)reduceBlock: 將所有序列的值減少為一個值的block轩猩。 它必須采用與給定序列數(shù)一樣多的參數(shù)。 每個參數(shù)都是一個對象參數(shù)羞迷。 返回值必須是對象界轩。 這個參數(shù)不能是nil画饥。
// 實例:
///   [RACSequence zip:@[ stringSequence, intSequence ]
///       reduce:^(NSString *string, NSNumber *number) {
///           return [NSString stringWithFormat:@"%@: %@", string, number];
///       }];
// 返回一個新序列衔瓮,其中包含每次調用`reduceBlock`的結果。
+ (RACSequence<ValueType> *)zip:(id<NSFastEnumeration>)sequences reduce:(RACReduceBlock)reduceBlock;
+ 
// 返回通過按順序連接“sequences”獲得的序列抖甘。
+ (RACSequence<ValueType> *)concat:(id<NSFastEnumeration>)sequences;

// 使用給定的block從左到右組合接收器中的值热鞍。
// 算法如下:
// 1. `startingValue`作為`running`值傳遞給block,接收器的第一個元素作為`next`值傳遞給block。
// 2. 調用的結果將添加到返回的序列中薇宠。
// 3. 調用(`running`)的結果和接收器的下一個元素(`next`)被傳遞給`block`偷办。
// 4. 重復步驟2和3,直到處理完所有值澄港。
// 參數(shù)startingValue: 要與接收器的第一個元素組合的值椒涯。 該值可能是“nil”。
// 參數(shù)reduceBlock: 描述如何組合接收器值的block回梧。 如果接收方為空废岂,則永遠不會調用此block。 不能是nil狱意。
// 實例:
///      RACSequence *numbers = @[ @1, @2, @3, @4 ].rac_sequence;
///
///      // Contains 1, 3, 6, 10
///      RACSequence *sums = [numbers scanWithStart:@0 reduce:^(NSNumber *sum, NSNumber *next) {
///          return @(sum.integerValue + next.integerValue);
///      }];
// 返回一個由`reduceBlock`的每個應用程序組成的新序列湖苞。 如果接收器為空,則返回空序列详囤。
- (RACSequence *)scanWithStart:(nullable id)startingValue reduce:(id _Nullable (^)(id _Nullable running, ValueType _Nullable next))reduceBlock;

// 使用給定的block從左到右組合接收器中的值财骨,該block也采用從零開始的值索引。
// 參數(shù)startingValue: 要與接收器的第一個元素組合的值藏姐。 該值可能是“nil”隆箩。
// 參數(shù)reduceBlock: 描述如何組合接收器值的block。 此block將從零開始的索引值作為最后一個參數(shù)羔杨。 如果接收方為空摘仅,則永遠不會調用此block。 不能是nil问畅。
// 返回一個由`reduceBlock`的每個應用程序組成的新序列娃属。如果接收器為空,則返回空序列护姆。
- (RACSequence *)scanWithStart:(nullable id)startingValue reduceWithIndex:(id _Nullable (^)(id _Nullable running, ValueType _Nullable next, NSUInteger index))reduceBlock;

// 將每個先前值和當前值組合到一個對象中矾端。
// 此方法類似于-scanWithStart:reduce:,但只對前一個和當前值(而不是整個序列)進行操作卵皂,并且不會將`reduceBlock`的返回值傳遞給它的下一個調用秩铆。
// 參數(shù)start: 對于第一個值,該值作為`previous`傳遞給`reduceBlock`灯变。
// 參數(shù)reduceBlock: 將先前值和當前值組合在一起以創(chuàng)建減少值的block殴玛。 不能是nil。
// 實例:
///      RACSequence *numbers = [@[ @1, @2, @3, @4 ].rac_sequence;
///
///      // Contains 1, 3, 5, 7
///      RACSequence *sums = [numbers combinePreviousWithStart:@0 reduce:^(NSNumber *previous, NSNumber *next) {
///          return @(previous.integerValue + next.integerValue);
///      }];
// 返回一個新序列添祸,該序列由`reduceBlock`的每個應用程序的返回值組成滚粟。
- (RACSequence *)combinePreviousWithStart:(nullable ValueType)start reduce:(id _Nullable (^)(ValueType _Nullable previous, ValueType _Nullable current))reduceBlock;

// 取值直到給定的block返回“YES”。
// 返回接收器中未通過`predicate`的初始值的RACSequence刃泌。 如果`predicate`永遠不會返回`YES`凡壤,則返回與接收器等效的序列署尤。
- (RACSequence<ValueType> *)takeUntilBlock:(BOOL (^)(ValueType _Nullable x))predicate;

// 取值直到給定的block返回“NO”。
// 返回接收器中通過`predicate`的初始值的RACSequence亚侠。 如果`predicate`永遠不會返回`NO`曹体,則返回與接收器等效的序列。
- (RACSequence<ValueType> *)takeWhileBlock:(BOOL (^)(ValueType _Nullable x))predicate;

// 跳過值硝烂,直到給定block返回“YES”箕别。
// 返回一個序列,其中包含接收器的值滞谢,這些值遵循任何初始值未通過`predicate`究孕。 如果`predicate`永遠不會返回`YES`,則返回一個空序列爹凹。
- (RACSequence<ValueType> *)skipUntilBlock:(BOOL (^)(ValueType _Nullable x))predicate;

// 跳過值厨诸,直到給定block返回“NO”。
// 返回一個序列禾酱,其中包含接收器的值微酬,這些值遵循任何初始值通過`predicate`。 如果`predicate`永遠不會返回`NO`颤陶,則返回一個空序列颗管。
- (RACSequence<ValueType> *)skipWhileBlock:(BOOL (^)(ValueType _Nullable x))predicate;

// 返回-isEqual:與前一個值比較時返回NO的值序列。
- (RACSequence<ValueType> *)distinctUntilChanged;

常用宏

RAC(TARGET, ...)

RACSubscriptingAssignmentTrampoline.h文件中定義滓走。

// 將信號分配給對象屬性垦江,自動在每個“next”上設置給定的鍵路徑。 信號完成后搅方,綁定將自動清理比吭。
// 這個宏有兩個不同的版本:
// 1.RAC(TARGET, KEYPATH, NILVALUE): RAC(TARGET, KEYPATH, NILVALUE)將`TARGET`的`KEYPATH`綁定到給定信號。 如果信號發(fā)送'nil`值姨涡,則屬性將設置為“NILVALUE”衩藤。 對于對象屬性,`NILVALUE`本身可能是'nil`涛漂,但是NSValue應該用于原始屬性赏表,以避免在發(fā)送`nil`時發(fā)生異常。
// 2.RAC(TARGET, KEYPATH): RAC(TARGET, KEYPATH)與上面的相同匈仗,但是`NILVALUE`默認為`nil`瓢剿。
// 實例:
///  RAC(self, objectProperty) = objectSignal;
///  RAC(self, stringProperty, @"foobar") = stringSignal;
///  RAC(self, integerProperty, @42) = integerSignal;
// 注意: 在某些情況下,使用此宏可能是線程不安全的悠轩。
#define RAC(TARGET, ...) \
    metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__)) \
        (RAC_(TARGET, __VA_ARGS__, nil)) \
        (RAC_(TARGET, __VA_ARGS__))

/// Do not use this directly. Use the RAC macro above.
#define RAC_(TARGET, KEYPATH, NILVALUE) \
    [[RACSubscriptingAssignmentTrampoline alloc] initWithTarget:(TARGET) nilValue:(NILVALUE)][@keypath(TARGET, KEYPATH)]

RACObserve(TARGET, KEYPATH)

NSObject+RACPropertySubscribing.h文件中定義
注意: RACObserve隱式引用了self间狂,在使用時注意防止循環(huán)引用造成內存泄漏的問題。

// 創(chuàng)建一個信號哗蜈,在“TARGET”上觀察“KEYPATH”的變化前标。
// 在任何一種情況下,觀察一直持續(xù)到“TARGET”或者self被銷毀距潘。 如果替代銷毀任何中間對象炼列,則假定它已設置為nil。
// 在block中使用此宏時音比,確保`@strongify(self)`俭尖! 宏將始終引用`self`,它可以在block中靜默引入保留循環(huán)洞翩。 因此稽犁,在使用`RACObserve`的表達式之前,應該確保`self`是一個弱引用(例如骚亿,由`@ weakify`和`@ strongify`創(chuàng)建)已亥。
// 實例:
///    // 觀察 self, 直到self被銷毀.
///    RACSignal *selfSignal = RACObserve(self, arrayController.items);
///
///    // 觀察self.arrayController,直到self或arrayController被銷毀
///    RACSignal *arrayControllerSignal = RACObserve(self.arrayController, items);
///
///    // 觀察 obj.arrayController, 直到self或arrayController被銷毀
///    RACSignal *signal2 = RACObserve(obj.arrayController, items);
///
///    @weakify(self);
///    RACSignal *signal3 = [anotherSignal flattenMap:^(NSArrayController *arrayController) {
///        // 由于RACObserve隱式引用了self,因此要防止循環(huán)引用
///        @strongify(self);
///        return RACObserve(arrayController, items);
///    }];
#define _RACObserve(TARGET, KEYPATH) \
({ \
    __weak id target_ = (TARGET); \
    [target_ rac_valuesForKeyPath:@keypath(TARGET, KEYPATH) observer:self]; \
})

#if __clang__ && (__clang_major__ >= 8)
#define RACObserve(TARGET, KEYPATH) _RACObserve(TARGET, KEYPATH)
#else
#define RACObserve(TARGET, KEYPATH) \
({ \
    _Pragma("clang diagnostic push") \
    _Pragma("clang diagnostic ignored \"-Wreceiver-is-weak\"") \
    _RACObserve(TARGET, KEYPATH) \
    _Pragma("clang diagnostic pop") \
})
#endif

ReactiveCococa優(yōu)質學習資源(排名不分先后)

美團技術團隊-ReactiveCocoa核心元素與信號流
美團技術團隊-ReactiveCocoa中潛在的內存泄漏及解決方案
美團技術團隊-細說ReactiveCocoa的冷信號與熱信號(三):怎么處理冷信號與熱信號
美團技術團隊-細說ReactiveCocoa的冷信號與熱信號(二):為什么要區(qū)分冷熱信號
美團技術團隊-細說ReactiveCocoa的冷信號與熱信號(一)
美團技術團隊-RACSignal的Subscription深入分析
唐巧-ReactiveCocoa 討論會
唐巧-ReactiveCocoa - iOS開發(fā)的新框架
NSHisper-Reactive?Cocoa
戴銘-從 ReactiveCocoa 中能學到什么来屠?不用此庫也能學以致用
戴銘-iOS函數(shù)響應式編程以及ReactiveCocoa的使用
戴銘-使用ReactiveCocoa開發(fā)RSS閱讀器
sunnyxx-Reactive Cocoa Tutorial 4 = 只取所需的Filters
sunnyxx-Reactive Cocoa Tutorial 3 = RACSignal的巧克力工廠
sunnyxx-Reactive Cocoa Tutorial 2 = 百變RACStream
sunnyxx-Reactive Cocoa Tutorial 1 = 神奇的Macros
sunnyxx-Reactive Cocoa Tutorial 0 = Overview
一縷殤流化隱半邊冰霜-ReactiveCocoa 中 RACSignal 是如何發(fā)送信號的
一縷殤流化隱半邊冰霜-ReactiveCocoa 中 RACSignal 所有變換操作底層實現(xiàn)分析(上)
一縷殤流化隱半邊冰霜-ReactiveCocoa 中 RACSignal 所有變換操作底層實現(xiàn)分析(中)
一縷殤流化隱半邊冰霜-ReactiveCocoa 中 RACSignal 所有變換操作底層實現(xiàn)分析(下)
一縷殤流化隱半邊冰霜-ReactiveCocoa 中 RACSignal 冷信號和熱信號底層實現(xiàn)分析
一縷殤流化隱半邊冰霜-ReactiveCocoa 中 集合類RACSequence 和 RACTuple底層實現(xiàn)分析
一縷殤流化隱半邊冰霜-ReactiveCocoa 中 RACScheduler是如何封裝GCD的
一縷殤流化隱半邊冰霜-ReactiveCocoa 中 RACCommand底層實現(xiàn)分析
一縷殤流化隱半邊冰霜-ReactiveCocoa 中 奇妙無比的“宏”魔法
袁崢-最快讓你上手ReactiveCocoa之基礎篇
袁崢-最快讓你上手ReactiveCocoa之進階篇
limboy-ReactiveCocoa2實戰(zhàn)
limboy-說說ReactiveCocoa 2
limboy-ReactiveCocoa與Functional Reactive Programming
Draveness-『狀態(tài)』驅動的世界:ReactiveCocoa
Draveness-Pull-Driven 的數(shù)據(jù)流 RACSequence
Draveness-『可變』的熱信號 RACSubject
Draveness-優(yōu)雅的 RACCommand
Draveness-用于多播的 RACMulticastConnection
Draveness-RAC 中的雙向數(shù)據(jù)綁定 RACChannel
Draveness-理解 RACScheduler 的實現(xiàn)
Draveness-從代理到 RACSignal
楊蕭玉-ReactiveCocoa 和 MVVM 入門
南峰子-ReactiveCocoa Tutorial – The Definitive Introduction: Part 1/2
南峰子-ReactiveCocoa Tutorial – The Definitive Introduction: Part 2/2
南峰子-MVVM Tutorial with ReactiveCocoa: Part 1/2
南峰子-MVVM Tutorial with ReactiveCocoa: Part 2/2
南峰子-Binding To A UITableView From A ReactiveCocoa ViewModel

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末虑椎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子俱笛,更是在濱河造成了極大的恐慌捆姜,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件迎膜,死亡現(xiàn)場離奇詭異泥技,居然都是意外死亡,警方通過查閱死者的電腦和手機磕仅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門珊豹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人榕订,你說我怎么就攤上這事平夜。” “怎么了卸亮?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵忽妒,是天一觀的道長。 經(jīng)常有香客問我兼贸,道長段直,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任溶诞,我火速辦了婚禮鸯檬,結果婚禮上,老公的妹妹穿的比我還像新娘螺垢。我一直安慰自己喧务,他們只是感情好赖歌,可當我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著功茴,像睡著了一般庐冯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上坎穿,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天展父,我揣著相機與錄音,去河邊找鬼玲昧。 笑死栖茉,一個胖子當著我的面吹牛,可吹牛的內容都是我干的孵延。 我是一名探鬼主播吕漂,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼尘应!你這毒婦竟也來了痰娱?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤菩收,失蹤者是張志新(化名)和其女友劉穎梨睁,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體娜饵,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡坡贺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了箱舞。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片遍坟。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖晴股,靈堂內的尸體忽然破棺而出愿伴,到底是詐尸還是另有隱情,我是刑警寧澤电湘,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布隔节,位于F島的核電站,受9級特大地震影響寂呛,放射性物質發(fā)生泄漏怎诫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一贷痪、第九天 我趴在偏房一處隱蔽的房頂上張望幻妓。 院中可真熱鬧,春花似錦劫拢、人聲如沸肉津。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽妹沙。三九已至偶洋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間初烘,已是汗流浹背涡真。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工分俯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留肾筐,地道東北人。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓缸剪,卻偏偏與公主長得像吗铐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子杏节,可洞房花燭夜當晚...
    茶點故事閱讀 45,455評論 2 359

推薦閱讀更多精彩內容