来自 rac_sequance 的 RACSignal 未正确传递信号
RACSignal from rac_sequance is not delivering signals correctly
我正在玩一些关于 Reactive Cocoa 的书中的代码,我被这本书困住了:
这是我的照片导入程序代码:
+ (RACSignal *)importPhotos {
NSURLRequest *request = [self popularURLRequest];
return [[[[[[NSURLConnection rac_sendAsynchronousRequest:request] map:^id(RACTuple *value) {
return [value second];
}] deliverOn:[RACScheduler mainThreadScheduler]]
map:^id(NSData *value) {
id result = [NSJSONSerialization JSONObjectWithData:value
options:0
error:nil];
return [[[result[@"photos"] rac_sequence] map:^id(NSDictionary *photoDictionary) {
FRPPhotoModel *photoModel = [FRPPhotoModel new];
[self configurePhotoModel:photoModel withDict:photoDictionary];
[self downloadThumbnailForPhotoModel:photoModel];
return photoModel;
}] array];
}] publish] autoconnect];
}
+ (void)configurePhotoModel:(FRPPhotoModel *)photoModel withDict:(NSDictionary *)dict {
photoModel.photoName = dict[@"name"];
photoModel.identifier = dict[@"id"];
photoModel.photographerName = dict[@"user"][@"username"];
photoModel.rating = dict[@"rating"];
[[self urlForImageSize:3 inArray:dict[@"images"]] subscribeNext:^(id x) {
photoModel.thumbnailURL = x;
}];
}
+ (RACSignal *)urlForImageSize:(NSInteger)size inArray:(NSArray *)array {
return [[[[array rac_sequence] filter:^BOOL(NSDictionary *value) {
return [value[@"size"] integerValue] == size;
}] map:^id(NSDictionary *value) {
return value[@"url"];
}] signal];
}
+ (void)downloadThumbnailForPhotoModel:(FRPPhotoModel *)photoModel {
[[RACObserve(photoModel, thumbnailURL) flattenMap:^RACStream *(id value) {
return [self download:value];
}] subscribeNext:^(id x) {
photoModel.thumbnailData = x;
}];
}
+ (RACSignal *)download:(NSString *)urlString {
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
return [[NSURLConnection rac_sendAsynchronousRequest:request] map:^id(RACTuple *value) {
return [value second];
}];
}
和UI更新如下:
RAC(self.imageView, image) = [[RACObserve(self, photoModel.thumbnailData) filter:^BOOL(id value) {
return value != nil;
}] map:^id(id value) {
return [UIImage imageWithData:value];
}];
你能解释一下为什么我的 UI 没有更新或错误地更新了新的 UI 我从那个 NSData 对象获得的图像。
所以第一个问题是 flattenMap 在一些后台 RACScheduler 上交付。改为:
[[[[RACObserve(photoModel, thumbnailURL) ignore:nil] flattenMap:^RACStream *(id value) {
return [self download:value];
}] deliverOn:[RACScheduler mainThreadScheduler]] subscribeNext:^(id x) {
photoModel.thumbnailData = x;
}];
另一个问题是 download:nil 抛出一个错误,该错误没有被订阅者捕获,因此终止了提供观察值的信号。添加 ignore:nil 已修复的问题。
我正在玩一些关于 Reactive Cocoa 的书中的代码,我被这本书困住了: 这是我的照片导入程序代码:
+ (RACSignal *)importPhotos {
NSURLRequest *request = [self popularURLRequest];
return [[[[[[NSURLConnection rac_sendAsynchronousRequest:request] map:^id(RACTuple *value) {
return [value second];
}] deliverOn:[RACScheduler mainThreadScheduler]]
map:^id(NSData *value) {
id result = [NSJSONSerialization JSONObjectWithData:value
options:0
error:nil];
return [[[result[@"photos"] rac_sequence] map:^id(NSDictionary *photoDictionary) {
FRPPhotoModel *photoModel = [FRPPhotoModel new];
[self configurePhotoModel:photoModel withDict:photoDictionary];
[self downloadThumbnailForPhotoModel:photoModel];
return photoModel;
}] array];
}] publish] autoconnect];
}
+ (void)configurePhotoModel:(FRPPhotoModel *)photoModel withDict:(NSDictionary *)dict {
photoModel.photoName = dict[@"name"];
photoModel.identifier = dict[@"id"];
photoModel.photographerName = dict[@"user"][@"username"];
photoModel.rating = dict[@"rating"];
[[self urlForImageSize:3 inArray:dict[@"images"]] subscribeNext:^(id x) {
photoModel.thumbnailURL = x;
}];
}
+ (RACSignal *)urlForImageSize:(NSInteger)size inArray:(NSArray *)array {
return [[[[array rac_sequence] filter:^BOOL(NSDictionary *value) {
return [value[@"size"] integerValue] == size;
}] map:^id(NSDictionary *value) {
return value[@"url"];
}] signal];
}
+ (void)downloadThumbnailForPhotoModel:(FRPPhotoModel *)photoModel {
[[RACObserve(photoModel, thumbnailURL) flattenMap:^RACStream *(id value) {
return [self download:value];
}] subscribeNext:^(id x) {
photoModel.thumbnailData = x;
}];
}
+ (RACSignal *)download:(NSString *)urlString {
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
return [[NSURLConnection rac_sendAsynchronousRequest:request] map:^id(RACTuple *value) {
return [value second];
}];
}
和UI更新如下:
RAC(self.imageView, image) = [[RACObserve(self, photoModel.thumbnailData) filter:^BOOL(id value) {
return value != nil;
}] map:^id(id value) {
return [UIImage imageWithData:value];
}];
你能解释一下为什么我的 UI 没有更新或错误地更新了新的 UI 我从那个 NSData 对象获得的图像。
所以第一个问题是 flattenMap 在一些后台 RACScheduler 上交付。改为:
[[[[RACObserve(photoModel, thumbnailURL) ignore:nil] flattenMap:^RACStream *(id value) {
return [self download:value];
}] deliverOn:[RACScheduler mainThreadScheduler]] subscribeNext:^(id x) {
photoModel.thumbnailData = x;
}];
另一个问题是 download:nil 抛出一个错误,该错误没有被订阅者捕获,因此终止了提供观察值的信号。添加 ignore:nil 已修复的问题。