我的任务是为应用程序添加一些检测逻辑,以跟踪各种API调用的延迟。我正在努力想出一种干净的,无副作用的方法来为返回RACSignal(延迟执行API调用)的方法添加时序检测。
completed
事件时记录时间我唯一能想到的就是创建一个处理定时器逻辑的具体RACSubscriber子类。除了令人讨厌的子类,这显然不理想,因为它需要一个明确的subscribe:
,这反过来要求源信号replay
。此外,调用者还有一个负担,因为他们必须至少重构以获得信号的临时句柄。
@interface SignalTimer : RACSubscriber
@property (nonatomic) NSDate *startDate;
@end
@implementation SignalTimer
- (void)didSubscribeWithDisposable:(RACDisposable *)disposable
{
[super didSubscribeWithDisposable:disposable];
self.startDate = [NSDate date];
}
- (void)sendCompleted
{
NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:self.startDate];
NSLog(@"Time elapsed: %f", duration);
[super sendCompleted];
}
@end
用法如下:
- (RACSignal*)saveFoo:(Foo*)fooParseObj {
RACSignal *save = [[fooParseObj rac_save] replay]; // Don't forget replay!
[save subscribe:[[SignalTimer alloc] initWithName@"Saving the user's foo object"]];
return save;
}
显然,我对这种实施不满意。
理想情况下,我想要一个像这样的链式方法,但是我不知道如何实现它/如果可以在类别方法中处理冷信号而没有令人讨厌的副作用(比如调用{接收器上的{1}}。
replay
思想?
答案 0 :(得分:2)
所以我认为我的做法比以前更难。以下类别解决方案似乎更惯用,但我喜欢任何反馈。
@interface RACSignal (Timing)
- (instancetype)logTimingWithName:(NSString*)name;
@end
@implementation RACSignal (Timing)
- (instancetype)logTimingWithName:(NSString*)name
{
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSDate* startDate = [NSDate date];
return [self subscribeNext:^(id x) {
[subscriber sendNext:x];
} error:^(NSError *error) {
[subscriber sendError:error];
} completed:^{
NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:startDate];
NSLog(@"%@: %f sec", name, duration);
[subscriber sendCompleted];
}];
}];
}
@end