常用類
RACSignal類
// 創(chuàng)建一個信號
// 每當一個新的subscriber訂閱時,會調(diào)用didSubscribe
// 內(nèi)部實現(xiàn):
// 1. 調(diào)用RACDynamicSignal的createSignal:方法,并返回RACDynamicSignal實例對象
// 2. RACDynamicSignal的createSignal:方法內(nèi)部,首先實例化一個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
// 方法內(nèi)部實現(xiàn):
// 1. 根據(jù)傳入的參數(shù)nextBlock創(chuàng)建RACSubscriber類的實例對象o, 對象o持有nextBlock。
// 2. 調(diào)用subscribe:方法,如果調(diào)用者是子類RACDynamicSignal對象,會調(diào)用其子類方法subscribe:,并返回一個disposable
// 3. RACDynamicSignal的subscribe:方法內(nèi)部:
// 3.1 創(chuàng)建RACCompoundDisposable對象disposable
// 3.2 根據(jù)self, subscriber(對象o),disposable三個參數(shù)生成一個RACPassthroughSubscriber對象subscriber,
// 3.3 如果_didSubscribe有值,會使用RACScheduler的subscriptionScheduler方法獲取單例對象,并調(diào)用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的信號
// 方法內(nèi)部調(diào)用RACReturnSignal類的return:方法
+ (RACSignal<ValueType> *)return:(nullable ValueType)value;
// 返回一個RACEmptySignal信號, 會立即發(fā)送complete的信號
+ (RACSignal<ValueType> *)empty;
// 只改變當前流對象
// 將block懶綁定到接受者的值
// 只有在需要提前終止綁定或關(guān)閉某個狀態(tài)時才應(yīng)該使用此選項。 -flattenMap:更適合所有其他情況。
// 參數(shù)block: 返回RACSignalBindBlock的block。 每次重新評估綁定信號時,都會調(diào)用此block。 此block不能為nil或返回nil。
// 返回值: 返回一個新信號,表示所有`block`的惰性應(yīng)用的組合結(jié)果。
- (RACSignal *)bind:(RACSignalBindBlock (^)(void))block;
// 在當前響應(yīng)流已經(jīng)完成后,緊接著注入新的響應(yīng)流
// 當源信號完成時,訂閱“signal”。
- (RACSignal *)concat:(RACSignal *)signal;
// 是將不同的流進行打包合成一個流
// 使用給定信號的值將接收器中的值壓縮以創(chuàng)建RACTuples。
// 每個信號的第一個“next”將被組合,然后是第二個“next”,依此類推,直到信號完成或出現(xiàn)錯誤。
// 參數(shù)signal: 要壓縮的信號,不能為nil
// 返回值: 返回RACTuples的新信號,表示兩個信號的組合值。 其中一個原始信號的任何錯誤都將在返回的信號上轉(zhuǎn)發(fā)。
- (RACSignal<RACTwoTuple<ValueType, id> *> *)zipWith:(RACSignal *)signal;
RACSignal(RACStreamOperations)
// 封裝bind操作, 將多個流的值映射到接受者上并生成一個新的流
// 將“block”映射到接收器中的值并使結(jié)果變平。
// 請注意,在-flattenMap之后應(yīng)用的運算符與-flattenMap:中的運算符的行為不同。 請參閱下面的示例部分。
// 這對應(yīng)于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;
// 將多個流拼接為一個流
// 使組合信號變平。
// 對應(yīng)于Rx中的`Merge`方法。
// 返回由接收器獲得的組合信號組成的信號。
- (RACSignal *)flatten;
// 將一個流的值通過轉(zhuǎn)換,映射形成一個新的流
// 這對應(yīng)于Rx中的“Select”方法。
// 返回帶有映射值的新信號。
- (RACSignal *)map:(id _Nullable (^)(ValueType _Nullable value))block;
// 直接使用object替換當前流的值并生成一個新的流
// 為接收器中的每個值返回一個新信號,其中包含給定對象一次。
- (RACSignal *)mapReplace:(nullable id)object;
// 使用block來驗證每個值,將驗證結(jié)果通過的值生成新的流
// 過濾掉未通過給定測試的接收器中的值。
// 這對應(yīng)于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: 要結(jié)合的信號。 如果此集合為空,則返回的信號將為空。
// 返回包含信號中壓縮值的RACTuples的新信號。
+ (RACSignal<RACTuple *> *)zip:(id<NSFastEnumeration>)signals;
// 使用+ zip:壓縮信號,然后使用-reduceEach將生成的元組減少為單個值:
// 參數(shù)signals: 要結(jié)合的信號。 如果此集合為空,則返回的信號將為空。
// 參數(shù)reduceBlock: 將所有信號的值減少為一個值的block。 它必須采用與給定信號數(shù)量一樣多的參數(shù)。 每個參數(shù)都是一個對象參數(shù)。 返回值必須是對象。 這個參數(shù)不能是nil。
// 實例:
/// [RACSignal zip:@[ stringSignal, intSignal ]
/// reduce:^(NSString *string, NSNumber *number) {
/// return [NSString stringWithFormat:@"%@: %@", string, number];
/// }];
// 返回一個新信號,其中包含每次調(diào)用`reduceBlock`的結(jié)果。
+ (RACSignal<ValueType> *)zip:(id<NSFastEnumeration>)signals reduce:(RACGenericReduceBlock)reduceBlock;
// 將新的流拼接到接受者后面
// 返回通過按順序連接`signals`獲得的信號
+ (RACSignal<ValueType> *)concat:(id<NSFastEnumeration>)signals;
// 使用給定的block從左到右組合接收器中的值。
// 算法如下:
// 1. `startingValue`作為`running`值傳遞給block,接收器的第一個元素作為`next`值傳遞給block。
// 2. 調(diào)用的結(jié)果將添加到返回的信號中
// 3. 調(diào)用(`running`)的結(jié)果和接收器的下一個元素(`next`)被傳遞給`block`。
// 重復(fù)步驟2和3,直到處理完所有值。
// 參數(shù)startingValue: 要與接收器的第一個元素組合的值。 該值可能是“nil”。
// 參數(shù)reduceBlock: 描述如何組合接收器值的block。 如果接收方為空,則永遠不會調(diào)用此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`的每個應(yīng)用程序組成的新信號。 如果接收器為空,則返回空信號。
- (RACSignal *)scanWithStart:(nullable id)startingValue reduce:(id _Nullable (^)(id _Nullable running, ValueType _Nullable next))reduceBlock;
// 用同樣的block執(zhí)行每次流中的值,并將結(jié)果用于后一次執(zhí)行當中,每次都把block執(zhí)行后的值變成新的流中的對象
// 使用給定的block從左到右組合接收器中的值,該block也采用從零開始的值索引。
// 參數(shù)startingValue: 要與接收器的第一個元素組合的值。 該值可能是“nil”。
// 參數(shù)reduceBlock: 描述如何組合接收器值的block。 此block將從零開始的索引值作為最后一個參數(shù)。 如果接收方為空,則永遠不會調(diào)用此block。 不可能是nil。
// 返回一個由`reduceBlock`的每個應(yīng)用程序組成的新信號。 如果接收器為空,則返回空信號。
- (RACSignal *)scanWithStart:(nullable id)startingValue reduceWithIndex:(id _Nullable (^)(id _Nullable running, ValueType _Nullable next, NSUInteger index))reduceBlock;
// 將每個先前值和當前值組合到一個對象中。
// 此方法類似于-scanWithStart:reduce:,但只對前一個和當前值(而不是整個信號)進行操作,并且不會將`reduceBlock`的返回值傳遞給它的下一個調(diào)用。
// 參數(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`的每個應(yīng)用程序的返回值組成。
- (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)榭樟鳎?,直到當前值滿足提供的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。 這應(yīng)該用于將side effects(副作用)注入信號。
- (RACSignal<ValueType> *)doNext:(void (^)(ValueType _Nullable x))block;
// 在`error`上執(zhí)行給定的block。 這應(yīng)該用于將side effects(副作用)注入信號。
- (RACSignal<ValueType> *)doError:(void (^)(NSError * _Nonnull error))block;
// 在`completed`上執(zhí)行給定的block。 這應(yīng)該用于將side effects(副作用)注入信號。
- (RACSignal<ValueType> *)doCompleted:(void (^)(void))block;
// 只有當在`interval`秒內(nèi)沒有收到另一個`next`時才發(fā)送`next`s。
// 如果接收到“next”,然后在“interval”秒之前接收到另一個“next”,則丟棄第一個值.
// 在自最近的`next`被發(fā)送以來已經(jīng)過了`interval`秒之后,最新的`next`在調(diào)度程序上被轉(zhuǎn)發(fā),該值最初被接收。 如果當時+ [RACScheduler currentScheduler]為nil,則使用私有后臺調(diào)度程序。
// 返回發(fā)送限制和延遲的“next”事件的信號。 始終會立即轉(zhuǎn)發(fā)完成和錯誤。
- (RACSignal<ValueType> *)throttle:(NSTimeInterval)interval;
// 當predicate返回YES時節(jié)流'next'
// 當predicate為'next'返回YES時:
// 1. 如果在“interval”秒之前接收到另一個“next”,則丟棄先前值。 無論新值是否受到限制,都會發(fā)生這種情況。
// 2. 自最初收到值之后經(jīng)過`interval`秒后,它將在收到它的調(diào)度程序上轉(zhuǎn)發(fā)。 如果當時+ [RACScheduler currentScheduler]為nil,則使用私有后臺調(diào)度程序。
// 當`predicate`為`next`返回NO時,它立即被轉(zhuǎn)發(fā),沒有任何限制。
// 參數(shù)interval: 緩沖傳遞`predicate`的最新值的秒數(shù)。
// 參數(shù)predicate: 從接收器傳遞每個`next`,該block返回是否應(yīng)該限制給定值。 這個參數(shù)不能是nil。
// 返回發(fā)送`next`事件的信號,當`predicate`返回YES時受到限制。 始終會立即轉(zhuǎn)發(fā)完成和錯誤。
- (RACSignal<ValueType> *)throttle:(NSTimeInterval)interval valuesPassingTest:(BOOL (^)(id _Nullable next))predicate;
// 在當前調(diào)度程序(事件已發(fā)送到其上)上延遲“interval”秒后,轉(zhuǎn)發(fā)`next`和`completed`事件。
// 如果收到“next”或“completed”時+ [RACScheduler currentScheduler]為nil,則使用私有后臺調(diào)度程序。
// 返回發(fā)送延遲的`next`和`completed`事件的信號。 錯誤總是立即轉(zhuǎn)發(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: 返回信號將在其上傳遞其值的調(diào)度程序。 不能是nil或+ [RACScheduler immediateScheduler]。
// 返回一個信號,該信號在`scheduler`上的每個間隔發(fā)送緩沖值的RACTuples。 當接收器完成時,將立即發(fā)送任何當前緩沖的值。
- (RACSignal<RACTuple *> *)bufferWithTime:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler;
// 將所有接收者的'next'收集到NSArray中。 Nil值將轉(zhuǎn)換為NSNull。
// 這對應(yīng)于Rx中的`ToArray`方法。
// 返回當接收器成功完成時發(fā)送單個NSArray的信號。
- (RACSignal<NSArray<ValueType> *> *)collect;
// 在接收信號完成后接受最后一次`count`'next's。
- (RACSignal<ValueType> *)takeLast:(NSUInteger)count;
// 一旦兩者都發(fā)送了至少一個`next`,將接收器和給定信號的最新值組合成2元組。
// 任何額外的`next`s將導(dǎo)致一個新的RACTuple,其中包含兩個信號的最新值。
// 參數(shù)signal: 與之相結(jié)合的信號。 這個參數(shù)不能是nil。
// 返回發(fā)送組合值的RACTuples的信號,轉(zhuǎn)發(fā)任何“錯誤”事件,并在兩個輸入信號完成時完成。
- (RACSignal<RACTwoTuple<ValueType, id> *> *)combineLatestWith:(RACSignal *)signal;
// 一旦所有信號都發(fā)送了至少一個`next`,就將給定信號的最新值合并到RACTuples中。
// 任何額外的`next`s將導(dǎo)致一個新的RACTuple,其中包含所有信號的最新值。
// 參數(shù)signals: 與之相結(jié)合的信號。如果此集合為空,則返回的信號將在訂閱后立即完成。
// 返回發(fā)送組合值的RACTuples的信號,轉(zhuǎn)發(fā)任何“錯誤”事件,并在所有輸入信號完成時完成。
+ (RACSignal<RACTuple *> *)combineLatest:(id<NSFastEnumeration>)signals;
// 使用+ combineLatest:組合信號,然后使用-reduceEach:將生成的元組減少為單個值。
// 參數(shù)signals: 與之相結(jié)合的信號。如果此集合為空,則返回的信號將在訂閱后立即完成。
// 參數(shù)reduceBlock: 將所有信號中的最新值減少為一個值的block。 它必須采用與給定信號數(shù)量一樣多的參數(shù)。 每個參數(shù)都是一個對象參數(shù)。 返回值必須是對象。 這個參數(shù)不能是nil。
// 實例:
/// [RACSignal combineLatest:@[ stringSignal, intSignal ] reduce:^(NSString *string, NSNumber *number) {
/// return [NSString stringWithFormat:@"%@: %@", string, number];
/// }];
// 返回一個信號,該信號發(fā)送每次調(diào)用`reduceBlock`的結(jié)果。
+ (RACSignal<ValueType> *)combineLatest:(id<NSFastEnumeration>)signals reduce:(RACGenericReduceBlock)reduceBlock;
// 用`+ merge:`合并接收器和給定信號并返回結(jié)果信號。
- (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;
// 匯總信號組的內(nèi)部信號。
- (RACSignal *)concat;
// 將接收器的“next”值聚合為單個組合值。
// 算法如下:
// 1. `start`作為`running`值傳遞給block,接收器的第一個元素作為`next`值傳遞給block。
// 2. 調(diào)用(`running`)的結(jié)果和接收器的下一個元素(`next`)被傳遞到`reduceBlock`。
// 3. 重復(fù)步驟2和3,直到處理完所有值。
// 4. `reduceBlock`的最后一個結(jié)果是在返回的信號上發(fā)送的。
// 此方法類似于-scanWithStart:reduce:,只是在返回的信號上僅發(fā)送最終結(jié)果。
// 參數(shù)start:要與接收器的第一個元素組合的值。 該值可能是“nil”。
// 參數(shù)reduceBlock: 描述如何組合接收器值的block。 如果接收方為空,則永遠不會調(diào)用此塊。 不能是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ù)。 如果接收方為空,則永遠不會調(diào)用此block。 不能是nil。
// 返回一個信號,該信號將在接收器完成時發(fā)送聚合值,然后自行完成。 如果接收方從不發(fā)送任何值,則會發(fā)送“start”。
- (RACSignal *)aggregateWithStart:(id)start reduceWithIndex:(id (^)(id running, id next, NSUInteger index))reduceBlock;
// 將接收器的“next”值聚合為單個組合值。
// 這會在每個訂閱上調(diào)用`startFactory`block,然后調(diào)用-aggregateWithStart:reduce:將block的返回值作為起始值。
// 參數(shù)startFactory: 返回將與接收器的第一個元素組合的起始值的block。 不能是nil。
// 參數(shù)reduceBlock: 描述如何組合接收器值的block。 如果接收方為空,則永遠不會調(diào)用此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: 應(yīng)在其上發(fā)送當前NSDate的調(diào)度程序。 這不能是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,也可以預(yù)期一些額外的延遲。
// 參數(shù)interval: ``next`s之間的基礎(chǔ)間隔。
// 參數(shù)scheduler: 應(yīng)在其上發(fā)送當前NSDate的調(diào)度程序。 這不能是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應(yīng)返回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應(yīng)返回非空值以指示操作成功。 此block不能為nil。
// 實例
/// // 如果無法從`fileURL`讀取數(shù)據(jù),則返回的信號將發(fā)送錯誤。
/// [signal tryMap:^(NSURL *fileURL, NSError **errorPtr) {
/// return [NSData dataWithContentsOfURL:fileURL options:0 error:errorPtr];
/// }];
// 返回一個轉(zhuǎn)換接收器所有值的信號。 如果`mapBlock`為任何值返回nil,則返回的信號將使用從block傳出的`NSError`錯誤。
- (RACSignal *)tryMap:(id (^)(id _Nullable value, NSError **errorPtr))mapBlock;
// 返回第一個`next`。 請注意,這是一個阻止調(diào)用。
- (nullable ValueType)first;
// 如果信號完成則返回第一個`next`或`defaultValue`或返回錯誤而不發(fā)送`next`。 請注意,這是一個阻止調(diào)用。
- (nullable ValueType)firstOrDefault:(nullable ValueType)defaultValue;
// 如果信號完成則返回第一個`next`或`defaultValue`或返回錯誤而不發(fā)送`next`。 如果發(fā)生錯誤,則成功將為NO并且將填充錯誤。 請注意,這是一個阻止調(diào)用。
// 成功和錯誤都可能為NULL。
- (nullable ValueType)firstOrDefault:(nullable ValueType)defaultValue success:(nullable BOOL *)success error:(NSError * _Nullable * _Nullable)error;
// 阻止調(diào)用者并等待信號完成。
// 參數(shù)error: 如果不為NULL,則設(shè)置為發(fā)生的任何錯誤。
// 返回信號是否成功完成。 如果為NO,則將“error”設(shè)置為發(fā)生的錯誤。
- (BOOL)waitUntilCompleted:(NSError * _Nullable * _Nullable)error;
// 延遲信號的創(chuàng)建,直到信號實際訂閱為止。
// 這可用于有效地將熱信號轉(zhuǎn)換為冷信號。
+ (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,則任何不匹配的值都將導(dǎo)致RACSignalErrorNoMatchingCase錯誤。
// 返回一個信號,它通過`case`或`defaultSignal`中的一個信號傳遞`next`s和`error`,并在`signal`和最后一個使用的信號完成時發(fā)送`completed`。 如果沒有給出`defaultSignal`,則不匹配的`next`將導(dǎo)致返回信號出錯。
+ (RACSignal<ValueType> *)switch:(RACSignal *)signal cases:(NSDictionary *)cases default:(nullable RACSignal *)defaultSignal;
// 根據(jù)`boolSignal`發(fā)送的最新值在`trueSignal`和`falseSignal`之間切換。
// 參數(shù)boolSignal: 確定“trueSignal”或“falseSignal”是否應(yīng)該激活的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代表。 請注意,這是一個阻止調(diào)用。
// 返回`next`值的數(shù)組,如果發(fā)生錯誤,則返回nil。
- (nullable NSArray<ValueType> *)toArray;
// 將每個`next`添加到序列中。 Nils由NSNulls代表。
// 返回一個序列,在發(fā)送信號時提供信號的值。 嘗試從尚未發(fā)送的序列中檢索值將阻止。
@property (nonatomic, strong, readonly) RACSequence<ValueType> *sequence;;
// 創(chuàng)建并返回多播連接。 這允許您共享對基礎(chǔ)信號的單個訂閱。
- (RACMulticastConnection<ValueType> *)publish;
// 創(chuàng)建并返回將值推送到給定subject的多播連接。 這允許您共享對基礎(chǔ)信號的單個訂閱。
- (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: 應(yīng)該發(fā)送任何超時錯誤的調(diào)度程序。 這不能是nil或+ [RACScheduler immediateScheduler]。
// 返回通過接收者事件的信號,直到流完成或超時,此時將在`scheduler`上發(fā)送錯誤。
- (RACSignal<ValueType> *)timeout:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler;
// 創(chuàng)建并返回在給定調(diào)度程序上傳遞其事件的信號。 接收器的任何side effects仍將在原始線程上執(zhí)行。
// 當信號已經(jīng)在所需的線程上執(zhí)行其工作,但您希望在其他地方處理其事件時,這是理想的。
- (RACSignal<ValueType> *)deliverOn:(RACScheduler *)scheduler;
// 創(chuàng)建并返回執(zhí)行其side effects的信號,并在給定的調(diào)度程序上傳遞其事件。
// 應(yīng)盡可能避免使用此運算符,因為接收器的side effects在另一個線程上運行可能不安全。 如果您只想在`scheduler`上接收信號的事件,請使用-deliverOn:代替。
- (RACSignal<ValueType> *)subscribeOn:(RACScheduler *)scheduler;
// 創(chuàng)建并返回在主線程上傳遞其事件的信號。 如果事件已經(jīng)在主線程上發(fā)送,則可以毫不拖延地傳遞它們。 如果在另一個線程上發(fā)送,或者如果先前的事件已在處理或已排隊,則事件將排隊等待以后在主線程上傳遞。
// 接收器的任何side effects仍將在原始線程上執(zhí)行。
// 當信號將導(dǎo)致UI更新時,可以使用此方法,以避免由延遲傳遞事件(例如視圖實例化時RACObserve中的第一個事件)引起的潛在閃爍。
- (RACSignal<ValueType> *)deliverOnMainThread;
// 將每個接收到的對象分組到一個組中,通過使用該對象調(diào)用“keyBlock”來確定。 通過使用對象調(diào)用`transformBlock`來轉(zhuǎn)換發(fā)送的對象。 如果`transformBlock`為nil,則發(fā)送原始對象。
// 返回的信號是RACGroupedSignal的信號。
- (RACSignal<RACGroupedSignal *> *)groupBy:(id<NSCopying> _Nullable (^)(id _Nullable object))keyBlock transform:(nullable id _Nullable (^)(id _Nullable object))transformBlock;
// 調(diào)用-[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ā),則返回的信號可以重復(fù)值。 來自`sampler`的值在接收器發(fā)送其第一個值之前被忽略。
// 參數(shù)sampler: 控制何時發(fā)送來自接收器的最新值的信號。 不能為nil。
- (RACSignal<ValueType> *)sample:(RACSignal *)sampler;
// 忽略接收器中的所有‘next’。
// 返回僅從接收器傳遞“error”或“completed”事件的信號。
- (RACSignal *)ignoreValues;
// 將每個接收者的事件轉(zhuǎn)換為RACEvent對象。
// 返回一個信號,它將接收者的事件作為RACEvents發(fā)送,并在接收者發(fā)送“completed”或“error”后完成。
- (RACSignal<RACEvent<ValueType> *> *)materialize;
// 將接收器中的每個RACEvent轉(zhuǎn)換回“真正的”RACSignal事件。
// 返回一個信號,為每個值RACEvent發(fā)送`next`,為每個錯誤RACEvent發(fā)送`error`,為每個完成的RACEvent發(fā)送`completed`。
- (RACSignal *)dematerialize;
// 反轉(zhuǎn)接收器發(fā)送的每個NSNumber包裝的BOOL。 如果接收者發(fā)送除NSNumbers之外的任何內(nèi)容,它將斷言。
// 返回反轉(zhuǎn)的NSNumber包裝的BOOL的信號。
- (RACSignal<NSNumber *> *)not;
// 在接收方發(fā)送的所有NSNumbers的RACTuple上執(zhí)行AND。
// 如果接收方發(fā)送除一個或多個NSNumber的RACTuple之外的任何內(nèi)容,則斷言。
// 返回一個信號,該信號對元組中的每個NSNumber應(yīng)用AND。
- (RACSignal<NSNumber *> *)and;
//在接收方發(fā)送的所有NSNumbers的RACTuple上執(zhí)行OR
// 如果接收方發(fā)送除一個或多個NSNumber的RACTuple之外的任何內(nèi)容,則斷言。
// 返回一個信號,該信號對元組中的每個NSNumber應(yīng)用OR。
- (RACSignal<NSNumber *> *)or;
// 使用接收器發(fā)送的每個RACTuple中打包的參數(shù)發(fā)送調(diào)用塊的結(jié)果。
// 接收器必須發(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];
// 返回將每個元組的第一個元素應(yīng)用于其余元素的結(jié)果的信號。
- (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)
// 調(diào)用保存的next這個block塊
- (void)sendNext:(id)value {...}
// 1. 調(diào)用self.disposable的dispose方法
// 2. 調(diào)用保存的error這個block塊
- (void)sendError:(NSError *)e {...}
// 1. 調(diào)用self.disposable的dispose方法
// 2. 調(diào)用保存的completed這個block塊
- (void)sendCompleted {...}
// 1. 給self.disposable添加一個otherDisposable
// 2. otherDisposable添加一個新創(chuàng)建的RACDisposable實例,并在創(chuàng)建時的block中,將otherDisposable從self.disposable中移除,避免內(nèi)存無限增加。
- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)otherDisposable {...}
RACCommand
通常,Command是響應(yīng)某些動作而觸發(fā)的信號
屬性
// 成功調(diào)用-execute返回的信號的信號:(即接收者“啟用”時)。
// 錯誤將自動捕獲內(nèi)部信號,并在“errors”上發(fā)送。 如果要接收內(nèi)部錯誤,請使用-execute:或 - [RACSignal materialize]。
// 只有在訂閱之后的執(zhí)行將根據(jù)此信號發(fā)送。所有內(nèi)部信號都將達到主線程
@property (nonatomic, strong, readonly) RACSignal<RACSignal<ValueType> *> *executionSignals;
// 發(fā)送這條命令是否正在執(zhí)行的信號
// 每當調(diào)用-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;
// 轉(zhuǎn)發(fā)-execute:返回的信號中發(fā)生的任何錯誤。
// 當從-execute:返回的信號發(fā)生錯誤時,該信號將相關(guān)的NSError值作為“next”事件發(fā)送(因為`error`事件將終止該流)。
// 訂閱后,此信號將在主線程上發(fā)送所有未來錯誤。
@property (nonatomic, strong, readonly) RACSignal<NSError *> *errors;
// 這條命令是否允許多個執(zhí)行同時進行。默認為NO
@property (atomic, assign) BOOL allowsConcurrentExecution;
方法
// 調(diào)用下面的方法,enabledSignal傳nil
- (instancetype)initWithSignalBlock:(RACSignal<ValueType> * (^)(InputType _Nullable input))signalBlock;
// 根據(jù)條件初始化一個command
// 參數(shù):
// enabledSignal: BOOL值的信號,指示是否應(yīng)該啟用命令。 `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. 調(diào)用初始化時給出的signalBlock
// 2. 將返回的信號多播到RACReplaySubject。
// 3. 在`executionSignals`上發(fā)送多播信號。
// 4. 訂閱(連接)主線程上的原始信號。
//
// 參數(shù)input: 傳遞給接收者的`signalBlock`的輸入值。 這可能是零
// 訂閱后返回多播信號。如果接受者不是enabled,則返回一個發(fā)送代碼為RACCommandErrorNotEnabled錯誤的信號。
- (RACSignal<ValueType> *)execute:(nullable InputType)input;
RACDisposable
負責(zé)清除訂閱所需的工作
// 接收器是否已被丟棄。
// 不鼓勵使用此屬性,因為它可以在任何時間同時設(shè)置為“是”
// 此屬性不符合KVO標準。
@property (atomic, assign, getter = isDisposed, readonly) BOOL disposed;
// 初始化
+ (instancetype)disposableWithBlock:(void (^)(void))block;
// 執(zhí)行清理工作。 可以多次調(diào)用,但后續(xù)調(diào)用不會執(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;
// 將序列轉(zhuǎn)換為急切序列。
// 急切的序列會立即全面評估其所有值。 來自急切序列的序列也將非??释?。
// 返回一個新的急切序列,如果序列已經(jīng)急切,則返回接收者。
@property (nonatomic, copy, readonly) RACSequence<ValueType> *eagerSequence;
// 將序列轉(zhuǎn)換為延遲序列。
// 延遲序列在訪問它們時按需評估其值。 衍生自惰性序列的序列也是惰性的。
// 返回一個新的延遲序列,如果序列已經(jīng)是惰性的,則返回接收者。
@property (nonatomic, copy, readonly) RACSequence<ValueType> *lazySequence;
// 使用新的RACScheduler調(diào)用-signalWithScheduler:。
- (RACSignal<ValueType> *)signal;
// 評估給定調(diào)度程序的完整序列。
// 每個項目在其自己的調(diào)度塊中進行評估,以便在每個值之間產(chǎn)生對調(diào)度程序的控制。
// 返回一個信號,該信號在給定的調(diào)度程序進行評估時發(fā)送接收器的值。
- (RACSignal<ValueType> *)signalWithScheduler:(RACScheduler *)scheduler;
// 對序列應(yīng)用左折疊。
// 這與迭代序列以及提供的起始值相同。 這使用恒定的內(nèi)存量。 左側(cè)折疊是左關(guān)聯(lián)的,因此在序列[1,2,3]中,塊將按以下順序應(yīng)用: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;
// 對序列應(yīng)用右折疊。
// 右側(cè)折疊相當于列表中的遞歸。 該列從列表中的右側(cè)到左側(cè)進行評估。 它是右關(guān)聯(lián)的,所以它首先應(yīng)用于最右邊的元素。 例如,在序列[1,2,3]中,塊按以下順序應(yīng)用:reduce(1,reduce(2,reduce(3,start)))
// 參數(shù)start: 折疊的起始值。
// 參數(shù)reduce: 用于組合累計值和下一個頭的塊。 該塊被賦予累積值和其余計算的值(遞歸的結(jié)果)。 使用`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: 第一次調(diào)用-head被訪問。
// 參數(shù)tailBlock: 第一次調(diào)用-tail被訪問。
// 每個塊的結(jié)果都被記憶,因此無論訪問序列的頭部和尾部屬性多次,每個塊最多只會被調(diào)用一次。
// `headBlock`或`tailBlock`中的任何side effects都應(yīng)該是線程安全的,因為可以在任何時候從任何線程計算序列。 不僅如此,可以在-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`設(shè)置為`YES`將導(dǎo)致綁定在返回值后終止。 返回“nil”將導(dǎo)致立即終止。
typedef RACSequence * _Nullable (^RACSequenceBindBlock)(ValueType _Nullable value, BOOL *stop);
// 延遲地將block綁定到接收器中的值。
// 只有在需要提前終止綁定或關(guān)閉某個狀態(tài)時才應(yīng)該使用此選項。 -flattenMap:更適合所有其他情況。
// 參數(shù)block: 返回RACSequenceBindBlock的block。 每次重新評估綁定序列時,都會調(diào)用此block。 此塊不能為nil或返回nil。
// 返回一個新序列,它表示`block`的所有惰性應(yīng)用程序的組合結(jié)果。
- (RACSequence *)bind:(RACSequenceBindBlock (^)(void))block;
// 源序列完成時訂閱`sequence`
- (RACSequence *)concat:(RACSequence *)sequence;
// 使用給定序列的值將接收器中的值壓縮以創(chuàng)建RACTuples。
// 每個序列的第一個“next”將被組合,然后是第二個“next”,依此類推,直到任一序列完成或錯誤。
// 參數(shù)sequence: 用來壓縮的序列,不能為nil
// 返回RACTuples的新序列,表示兩個序列的組合值。 原始序列之一的任何錯誤都將在返回的序列上轉(zhuǎn)發(fā)。
- (RACSequence<RACTuple *> *)zipWith:(RACSequence *)sequence;
RACStream(RACStreamOperations)
// 將“block”映射到接收器中的值并使結(jié)果變平。
// 參數(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: 要結(jié)合的序列。 如果此集合為空,則返回的序列將為空。
// 返回包含序列中壓縮值的RACTuples的新序列。
+ (RACSequence<RACTuple *> *)zip:(id<NSFastEnumeration>)sequence;
// 使用+ zip:壓縮序列,然后使用-reduceEach:將生成的元組減少為單個值。
// 參數(shù)sequences: 要結(jié)合的序列。 如果此集合為空,則返回的序列將為空。
// 參數(shù)reduceBlock: 將所有序列的值減少為一個值的block。 它必須采用與給定序列數(shù)一樣多的參數(shù)。 每個參數(shù)都是一個對象參數(shù)。 返回值必須是對象。 這個參數(shù)不能是nil。
// 實例:
/// [RACSequence zip:@[ stringSequence, intSequence ]
/// reduce:^(NSString *string, NSNumber *number) {
/// return [NSString stringWithFormat:@"%@: %@", string, number];
/// }];
// 返回一個新序列,其中包含每次調(diào)用`reduceBlock`的結(jié)果。
+ (RACSequence<ValueType> *)zip:(id<NSFastEnumeration>)sequences reduce:(RACReduceBlock)reduceBlock;
+
// 返回通過按順序連接“sequences”獲得的序列。
+ (RACSequence<ValueType> *)concat:(id<NSFastEnumeration>)sequences;
// 使用給定的block從左到右組合接收器中的值。
// 算法如下:
// 1. `startingValue`作為`running`值傳遞給block,接收器的第一個元素作為`next`值傳遞給block。
// 2. 調(diào)用的結(jié)果將添加到返回的序列中。
// 3. 調(diào)用(`running`)的結(jié)果和接收器的下一個元素(`next`)被傳遞給`block`。
// 4. 重復(fù)步驟2和3,直到處理完所有值。
// 參數(shù)startingValue: 要與接收器的第一個元素組合的值。 該值可能是“nil”。
// 參數(shù)reduceBlock: 描述如何組合接收器值的block。 如果接收方為空,則永遠不會調(diào)用此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`的每個應(yīng)用程序組成的新序列。 如果接收器為空,則返回空序列。
- (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ù)。 如果接收方為空,則永遠不會調(diào)用此block。 不能是nil。
// 返回一個由`reduceBlock`的每個應(yīng)用程序組成的新序列。如果接收器為空,則返回空序列。
- (RACSequence *)scanWithStart:(nullable id)startingValue reduceWithIndex:(id _Nullable (^)(id _Nullable running, ValueType _Nullable next, NSUInteger index))reduceBlock;
// 將每個先前值和當前值組合到一個對象中。
// 此方法類似于-scanWithStart:reduce:,但只對前一個和當前值(而不是整個序列)進行操作,并且不會將`reduceBlock`的返回值傳遞給它的下一個調(diào)用。
// 參數(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`的每個應(yīng)用程序的返回值組成。
- (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”上設(shè)置給定的鍵路徑。 信號完成后,綁定將自動清理。
// 這個宏有兩個不同的版本:
// 1.RAC(TARGET, KEYPATH, NILVALUE): RAC(TARGET, KEYPATH, NILVALUE)將`TARGET`的`KEYPATH`綁定到給定信號。 如果信號發(fā)送'nil`值,則屬性將設(shè)置為“NILVALUE”。 對于對象屬性,`NILVALUE`本身可能是'nil`,但是NSValue應(yīng)該用于原始屬性,以避免在發(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)引用造成內(nèi)存泄漏的問題。
// 創(chuàng)建一個信號,在“TARGET”上觀察“KEYPATH”的變化。
// 在任何一種情況下,觀察一直持續(xù)到“TARGET”或者self被銷毀。 如果替代銷毀任何中間對象,則假定它已設(shè)置為nil。
// 在block中使用此宏時,確保`@strongify(self)`! 宏將始終引用`self`,它可以在block中靜默引入保留循環(huán)。 因此,在使用`RACObserve`的表達式之前,應(yīng)該確保`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)質(zhì)學(xué)習(xí)資源(排名不分先后)
美團技術(shù)團隊-ReactiveCocoa核心元素與信號流
美團技術(shù)團隊-ReactiveCocoa中潛在的內(nèi)存泄漏及解決方案
美團技術(shù)團隊-細說ReactiveCocoa的冷信號與熱信號(三):怎么處理冷信號與熱信號
美團技術(shù)團隊-細說ReactiveCocoa的冷信號與熱信號(二):為什么要區(qū)分冷熱信號
美團技術(shù)團隊-細說ReactiveCocoa的冷信號與熱信號(一)
美團技術(shù)團隊-RACSignal的Subscription深入分析
唐巧-ReactiveCocoa 討論會
唐巧-ReactiveCocoa - iOS開發(fā)的新框架
NSHisper-Reactive?Cocoa
戴銘-從 ReactiveCocoa 中能學(xué)到什么?不用此庫也能學(xué)以致用
戴銘-iOS函數(shù)響應(yīng)式編程以及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之基礎(chǔ)篇
袁崢-最快讓你上手ReactiveCocoa之進階篇
limboy-ReactiveCocoa2實戰(zhàn)
limboy-說說ReactiveCocoa 2
limboy-ReactiveCocoa與Functional Reactive Programming
Draveness-『狀態(tài)』驅(qū)動的世界: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