The signal for button
RACSignal *buttonPressedSignal = [_valicodeGetButton rac_signalForControlEvents:UIControlEventTouchUpInside];
I try to flattenMap
the signal with a timer signal I create
[[buttonPressedSignal
flattenMap:^RACStream *(id value) {
return [Timer timerSignalWithInterval:1 repeateTime:5];
}]
subscribeNext:^(id x) {
@strongify(self)
[self.valicodeGetButton setTitle:[NSString stringWithFormat:@"%@", x] forState:UIControlStateNormal];
} completed:^{
self.viewModel.isValicodeGetEnabel = YES;
}];
but I can't get into the completed block.
this is the timer signal:
+ (RACSignal *)timerSignalWithInterval:(NSInteger)interval repeateTime:(NSInteger)repeateTime
{
__block int count = 0;
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[[[RACSignal interval:interval onScheduler:[RACScheduler mainThreadScheduler]]
take:repeateTime]
subscribeNext:^(id x) {
count++;
[subscriber sendNext:@(repeateTime - count)];
if (repeateTime - count == 0) {
[subscriber sendCompleted];
}
}];
return [RACDisposable new];
}];
}
Well, the signal you derive from flattenMap
won't complete until each of the returned sub-signals complete and the original signal completes (in this case, buttonPressedSignal
).
So even though each of your inner signals are completing properly, you're not going to see a completion for the outer signal until buttonPressedSignal
completes as well, which currently isn't going to happen until _valicodeGetButton
is deallocated.
As for fixing it, it depends on what you're trying to accomplish. Do you want to do this completion block after each of the inner signals completes? Are you only trying to run it once?
For tracking the inner values, nested subscriptions instead of flattenMap
is one easy way to fix this problem, but it's messy. For a nicer solution, check out materialize
instead as an alternative that will let you introspect on the inner signal's completion values from "outside" of the flattenMap
.
But that is only a speculative solution. I don't really know the intent here.
Side note: you can simplify timerSignalWithInterval:repeateTime:
to the following:
// note the changed types here
+ (RACSignal *)timerSignalWithInterval:(NSTimeInterval)interval count:(NSUInteger)count
{
__block NSUInteger i = 0;
return [[[RACSignal interval:interval onScheduler:[RACScheduler mainThreadScheduler]] take:count] map:^(id x) {
return @(i++);
}];
}
No need to create an explicit subscription just to change the value that the signal sends. (You can also write that using scanWithStart:reduce:
and eschew the __block
variable altogether, but it's a bit cumbersome in this case due to the boxing.)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.