ReactiveCocoa 倒计时日期
ReactiveCocoa countdown to date
刚开始使用 ReactiveCocoa 并慢慢转换我当前的代码以使用它。
现在我有一个倒计时到计时器完成的日期,只是我不确定如何在倒计时完成后停止计时器并在完成时执行另一个操作。
NSTimeInterval dateInSecond = 1440855240;
self.dateUntilNextEvent = [NSDate dateWithTimeIntervalSince1970:dateInSecond];
RACSignal *countdownSignal = [[[[RACSignal interval:1 onScheduler:[RACScheduler schedulerWithPriority:RACSchedulerPriorityBackground]]
startWith:[NSDate date]] map:^id(NSDate *value) {
if([self.dateUntilNextEvent earlierDate:value] == self.dateUntilNextEvent){
//Stop "timer" and call an onComeplete method
return @"0";
}
NSUInteger flags = NSDayCalendarUnit
| NSHourCalendarUnit
| NSMinuteCalendarUnit
| NSSecondCalendarUnit;
NSDateComponents *components = [[NSCalendar currentCalendar] components:flags
fromDate:value
toDate:self.dateUntilNextEvent options:0];
return [NSString stringWithFormat:@"%02ld : %02ld : %02ld : %02ld",
(long)[components day], (long)[components hour],
(long)[components minute], (long)[components second]];
}] deliverOn:RACScheduler.mainThreadScheduler];
RAC(self.countdownLabel,text) = countdownSignal;
如有任何帮助,我们将不胜感激,或者只是向哪个方向前进!
您可以使用 -takeUntilBlock:
在某些谓词变为真时关闭信号:
@weakify(self);
RAC(self.countdownLabel, text) =
[[[[[RACSignal interval:1
onScheduler:[RACScheduler schedulerWithPriority:RACSchedulerPriorityBackground]]
startWith:[NSDate date]]
takeUntilBlock:^BOOL(NSDate *date) {
@strongify(self);
return [self.dateUntilNextEvent compare:date] == NSOrderedAscending;
}]
map:^id(NSDate *date) {
// Your NSCalendar/NSString transformation here.
}]
deliverOn:RACScheduler.mainThreadScheduler];
完全无关:
您还提到您刚刚开始使用 ReactiveCocoa。新用户的陷阱之一是信号由对象保留,但信号由对同一对象进行强引用的块组成。
在您的 -map
中,您引用了 self
。因此,该块将获得 self
的所有权(增加其保留计数),然后当将该块提供给信号时,该信号将获得该块的所有权,最后当您将信号绑定到 self.countdownLabel
,您的 self
获得信号的所有权。
因此,请注意,在我的 -takeUntilBlock
中,我使用了 @weakify/@strongify
技术。请务必阅读此内容,否则您将在代码中引入循环保留。
刚开始使用 ReactiveCocoa 并慢慢转换我当前的代码以使用它。
现在我有一个倒计时到计时器完成的日期,只是我不确定如何在倒计时完成后停止计时器并在完成时执行另一个操作。
NSTimeInterval dateInSecond = 1440855240;
self.dateUntilNextEvent = [NSDate dateWithTimeIntervalSince1970:dateInSecond];
RACSignal *countdownSignal = [[[[RACSignal interval:1 onScheduler:[RACScheduler schedulerWithPriority:RACSchedulerPriorityBackground]]
startWith:[NSDate date]] map:^id(NSDate *value) {
if([self.dateUntilNextEvent earlierDate:value] == self.dateUntilNextEvent){
//Stop "timer" and call an onComeplete method
return @"0";
}
NSUInteger flags = NSDayCalendarUnit
| NSHourCalendarUnit
| NSMinuteCalendarUnit
| NSSecondCalendarUnit;
NSDateComponents *components = [[NSCalendar currentCalendar] components:flags
fromDate:value
toDate:self.dateUntilNextEvent options:0];
return [NSString stringWithFormat:@"%02ld : %02ld : %02ld : %02ld",
(long)[components day], (long)[components hour],
(long)[components minute], (long)[components second]];
}] deliverOn:RACScheduler.mainThreadScheduler];
RAC(self.countdownLabel,text) = countdownSignal;
如有任何帮助,我们将不胜感激,或者只是向哪个方向前进!
您可以使用 -takeUntilBlock:
在某些谓词变为真时关闭信号:
@weakify(self);
RAC(self.countdownLabel, text) =
[[[[[RACSignal interval:1
onScheduler:[RACScheduler schedulerWithPriority:RACSchedulerPriorityBackground]]
startWith:[NSDate date]]
takeUntilBlock:^BOOL(NSDate *date) {
@strongify(self);
return [self.dateUntilNextEvent compare:date] == NSOrderedAscending;
}]
map:^id(NSDate *date) {
// Your NSCalendar/NSString transformation here.
}]
deliverOn:RACScheduler.mainThreadScheduler];
完全无关:
您还提到您刚刚开始使用 ReactiveCocoa。新用户的陷阱之一是信号由对象保留,但信号由对同一对象进行强引用的块组成。
在您的 -map
中,您引用了 self
。因此,该块将获得 self
的所有权(增加其保留计数),然后当将该块提供给信号时,该信号将获得该块的所有权,最后当您将信号绑定到 self.countdownLabel
,您的 self
获得信号的所有权。
因此,请注意,在我的 -takeUntilBlock
中,我使用了 @weakify/@strongify
技术。请务必阅读此内容,否则您将在代码中引入循环保留。