ReactiveCocoa - 学会反应性思考

时间:2015-11-02 16:55:09

标签: ios objective-c reactive-cocoa

我目前正在调查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;
    }];
}

0 个答案:

没有答案