我目前正在调查ReactiveCocoa,虽然我已经对它的课程有点熟悉了,但我觉得我仍有一些问题需要反应思考。
如果有经验的人可以查看我的代码(已经正常工作)并指出我目前没有足够反应但只使用RAC类以经典方式实现的任何内容,我会感激不尽。
当然,你身边的任何例子都是首选。
简要介绍我的代码功能:
我向图像搜索API发送了几个异步请求,将结果作为链接数组,然后使用它们异步下载图像,最后通过用生成的新图像替换它来在大型UIImageView上绘制它们。每次下载新图像时。
谢谢!
- (void)fillImageView:(UIImageView *)imageView withQuery:(NSString *)query {
self.timestamp = [NSDate timeIntervalSinceReferenceDate];
[[[self searchAllSignalWithQuery:query]
map:^id(NSArray *images) {
NSLog(@"Processing images. Count: %ld", images.count);
return [self processSignalWithImages:images imageView:imageView];
}]
subscribeCompleted:^{
}];
}
- (RACSignal *)searchAllSignalWithQuery:(NSString *)query {
NSMutableArray *searchSignals = [NSMutableArray array];
for (NSInteger pageIndex = 0; pageIndex < kSearchPageCount; pageIndex++) {
[searchSignals addObject:[self searchSignalWithQuery:query top:kSearchPageSize skip:(pageIndex * kSearchPageSize)]];
}
return [[RACSignal zip:searchSignals] flattenMap:^id(NSArray *results) {
NSMutableArray *images = [NSMutableArray array];
for (NSArray *result in results) {
[images addObjectsFromArray:result];
}
return [RACSignal return:images];
}];
}
- (RACSignal *)searchSignalWithQuery:(NSString *)query top:(NSInteger)top skip:(NSInteger)skip {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSURLSessionDataTask *task = [Common searchTaskWithQuery:query top:top skip:skip completionBlock:^(NSArray *images) {
NSLog(@"Adding images. Count: %ld", images.count);
[subscriber sendNext:images];
[subscriber sendCompleted];
}];
[task resume];
return nil;
}];
}
- (RACSignal *)processSignalWithImages:(NSArray *)images imageView:(UIImageView *)imageView {
NSInteger imageIndex = 0;
NSMutableArray *downloadSignals = [NSMutableArray array];
RACScheduler *drawScheduler = [RACScheduler schedulerWithPriority:RACSchedulerPriorityDefault];
for (NSString *url in images) {
RACSignal *downloadSignal = [self downloadSignalWithURL:url];
[[downloadSignal deliverOn:[RACScheduler schedulerWithPriority:RACSchedulerPriorityBackground]] subscribeNext:^(UIImage *image) {
NSLog(@"Drawing image. Index: %ld", imageIndex);
if (!image) {
image = [UIImage imageNamed:@"error"];
}
[drawScheduler schedule:^{
UIImage *newImage = [Common imageByDrawingImage:image onImageView:imageView atIndex:imageIndex];
[[RACScheduler mainThreadScheduler] schedule:^{
imageView.image = newImage;
}];
}];
}];
[downloadSignals addObject:downloadSignal];
imageIndex++;
}
RACSignal *processSignal = [RACSignal combineLatest:downloadSignals];
[processSignal subscribeCompleted:^{
NSLog(@"Completed. Duration: %.2f seconds", ([NSDate timeIntervalSinceReferenceDate] - self.timestamp));
}];
return processSignal;
}
- (RACSignal *)downloadSignalWithURL:(NSString *)url {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSURLSessionDataTask *task = [Common downloadTaskWithURL:url completionBlock:^(UIImage *image) {
[subscriber sendNext:image];
[subscriber sendCompleted];
}];
[task resume];
return nil;
}];
}