RACDelegateProxy
用来实现代理,使用,将代理设置成RACDelegateProxy对象,并将RACDelegateProxy的rac_proxiedDelegate设置成之前的代理。
RACDelegateProxy *pro = [[RACDelegateProxy alloc] initWithProtocol:@protocol(UITableViewDelegate)];
[[pro rac_signalForSelector:@selector(tableView:didSelectRowAtIndexPath:)] subscribeNext:^(RACTuple * _Nullable x) {
NSLog(@"%@",x.second);
}];
_aav = pro;
pro.rac_proxiedDelegate = self;
self.tableView.delegate = pro;
RACCommand
初始化
- (instancetype)initWithSignalBlock:(RACSignal<id> * (^)(id input))signalBlock
- (instancetype)initWithEnabled:(RACSignal *)enabledSignal signalBlock:(RACSignal<id> * (^)(id input))signalBlock
上面的方法是调用下面的方法,不过传的值为nil
//创建两个热信号,copy传入的block
_addedExecutionSignalsSubject = [RACSubject new];
_allowsConcurrentExecutionSubject = [RACSubject new];
_signalBlock = [signalBlock copy];
_executionSignals
_executionSignals = [[[self.addedExecutionSignalsSubject
map:^(RACSignal *signal) {
return [signal catchTo:[RACSignal empty]];
}]
deliverOn:RACScheduler.mainThreadScheduler]
setNameWithFormat:@"%@ -executionSignals", self];
主要用来事件处理,执行的信号订阅添加执行的信号,接收的x是一个signal,并且在signal发送失败时转发为empty。在主线程上执行。
_errors
RACMulticastConnection *errorsConnection = [[[self.addedExecutionSignalsSubject
flattenMap:^(RACSignal *signal) {
return [[signal
ignoreValues]
catch:^(NSError *error) {
return [RACSignal return:error];
}];
}]
deliverOn:RACScheduler.mainThreadScheduler]
publish];
RACMulticastConnection *errorsConnection = [[[self.addedExecutionSignalsSubject
flattenMap:^(RACSignal *signal) {
return [[signal
ignoreValues]
catch:^(NSError *error) {
return [RACSignal return:error];
}];
}]
deliverOn:RACScheduler.mainThreadScheduler]
publish];
_errors = [errorsConnection.signal setNameWithFormat:@"%@ -errors", self];
[errorsConnection connect];
错误信号只捕获失败信号,并发送给订阅者,并转换为热信号。在主线程中执行。
immediateExecuting
_errors = [errorsConnection.signal setNameWithFormat:@"%@ -errors", self];
[errorsConnection connect];
RACSignal *immediateExecuting = [[[[self.addedExecutionSignalsSubject
flattenMap:^(RACSignal *signal) {
return [[[signal
catchTo:[RACSignal empty]]
then:^{
return [RACSignal return:@-1];
}]
startWith:@1];
}]
scanWithStart:@0 reduce:^(NSNumber *running, NSNumber *next) {
return @(running.integerValue + next.integerValue);
}]
map:^(NSNumber *count) {
return @(count.integerValue > 0);
}]
startWith:@NO];
这段代码可以这样分析:
1.分析对接受的信号的处理:
return [[[signal
catchTo:[RACSignal empty]]
then:^{
return [RACSignal return:@-1];
}]
startWith:@1];
(1)当信号发送错误信号的时候,转发信号为空信号
[signal
catchTo:[RACSignal empty]]
(2)忽略信号所有发送的值,并在发送完成后返回一个-1值
[signal then:^{
return [RACSignal return:@-1];
}]]
(3)先订阅一个返回值为1的信号
[signal startWith:@1]
这段代码结合起来,就是,订阅这个信号的时候,
1️⃣原信号如果发送失败的值得话会被转化为完成信号
2️⃣原信号如果发送其他值的化,都不接受,如果收到完成值,会在订阅信号执行完之后执行一个-1回调
3️⃣在执行信号之前,先执行一个1的回调
总结:若信号发送完成,则一共会调用一次1值和-1值,失败的话只发送1值,其他的不做处理
2.分析外围:
经过信号的转变,再进一步对获取的信号进行处理
(1)累加处理,没接收一次信号,就返回接收到的所有值的和
[signal scanWithStart:@0 reduce:^(NSNumber *running, NSNumber *next) {
return @(running.integerValue + next.integerValue);
}]
(2)如果返回的一个bool值,是否大于0
[signal map:^(NSNumber *count) {
return @(count.integerValue > 0);
}]
(3)在接受到信号的时候先执行一个0信号
[signal startWith:@NO]
immediateExecuting信号只会在发送完成和失败的时候才会调用:会给订阅者发送三个值:0,1,0,未完成的只会发送0,1
_executing
_executing = [[[[[immediateExecuting
deliverOn:RACScheduler.mainThreadScheduler]//在主线程中运行
// This is useful before the first value arrives on the main thread.
startWith:@NO]//刚上发送一个0
distinctUntilChanged]//除非有所改变否则不发送
replayLast]//记录上一个发送的信号,当有新的订阅者的时候,直接发送上一个的值
setNameWithFormat:@"%@ -executing", self];
moreExecutionsAllowed
RACSignal *moreExecutionsAllowed = [RACSignal
if:[self.allowsConcurrentExecutionSubject startWith:@NO]
then:[RACSignal return:@YES]
else:[immediateExecuting not]];
如果allowsConcurrentExecutionSubject发送的是YES的话订阅前面的signal,如果不是的话订阅的是后面的signal,这个signal的意思其实很明确,就是判断当前可不可以执行,如果可以,返回yes,如果不可以返回,当前是否在执行中。
enabledSignal
if (enabledSignal == nil) {
enabledSignal = [RACSignal return:@YES];
} else {
enabledSignal = [enabledSignal startWith:@YES];
}
有没有传入判断是否可以执行操作的判断,如果有,则先执行以下yes,在执行enableSignal,
否则一直返回yes。
_immediateEnabled
_immediateEnabled = [[[[RACSignal
combineLatest:@[ enabledSignal, moreExecutionsAllowed ]]//合并两个信号,返回的值是个两元元组
and]//两个值是否同时大于0
takeUntil:self.rac_willDeallocSignal]
replayLast];
这个用来判断是否可以执行点击操作
_enabled
_enabled = [[[[[self.immediateEnabled
take:1]
concat:[[self.immediateEnabled skip:1] deliverOn:RACScheduler.mainThreadScheduler]]
distinctUntilChanged]
replayLast]
setNameWithFormat:@"%@ -enabled", self];
同上。
BOOL enabled = [[self.immediateEnabled first] boolValue];
if (!enabled) {
NSError *error = [NSError errorWithDomain:RACCommandErrorDomain code:RACCommandErrorNotEnabled userInfo:@{
NSLocalizedDescriptionKey: NSLocalizedString(@"The command is disabled and cannot be executed", nil),
RACUnderlyingCommandErrorKey: self
}];
return [RACSignal error:error];
}
RACSignal *signal = self.signalBlock(input);
NSCAssert(signal != nil, @"nil signal returned from signal block for value: %@", input);
// We subscribe to the signal on the main thread so that it occurs _after_
// -addActiveExecutionSignal: completes below.
//
// This means that `executing` and `enabled` will send updated values before
// the signal actually starts performing work.
RACMulticastConnection *connection = [[signal
subscribeOn:RACScheduler.mainThreadScheduler]
multicast:[RACReplaySubject subject]];
[self.addedExecutionSignalsSubject sendNext:connection.signal];
[connection connect];
return [connection.signal setNameWithFormat:@"%@ -execute: %@", self, RACDescription(input)];
每次执行后,会根据input返回一个信号,然后self.addedExecutionSignalsSubject会发送这个信号,来执行上面的流程。
再来看下头文件我们可知:
//用来获取需要订阅的信号
@property (nonatomic, strong, readonly) RACSignal<RACSignal<ValueType> *> *executionSignals;
//获取执行的状态
@property (nonatomic, strong, readonly) RACSignal<NSNumber *> *executing;
//是否可执行
@property (nonatomic, strong, readonly) RACSignal<NSNumber *> *enabled;
//失败时发送的信号
@property (nonatomic, strong, readonly) RACSignal<NSError *> *errors;
//是否允许执行多次
@property (atomic, assign) BOOL allowsConcurrentExecution;
//让executionSignals动发送一次信号
- (RACSignal<ValueType> *)execute:(nullable InputType)input;
网友评论