Since ReactiveCocoa runs on the thread where it's been emitted, which means if you catch an asynchronous reulst from server and emit a signal, which will be run in the thread other than main thread, so to update UI will have a big problem.
Use the method "deliverOn" in RACScheduler class can put this signal run in the main thread.
[[[[[[self requestAccessToTwitterSignal]
then:^RACSignal *{
@strongify(self)
return self.searchText.rac_textSignal;
}]
filter:^BOOL(NSString *text) {
@strongify(self)
return [self isValidSearchText:text];
}]
flattenMap:^RACStream *(NSString *text) {
@strongify(self)
return [self signalForSearchWithText:text];
}]
deliverOn:[RACScheduler mainThreadScheduler]]
subscribeNext:^(id x) {
NSLog(@"%@", x);
} error:^(NSError *error) {
NSLog(@"An error occurred: %@", error);
}];
利用RACScheduler来异步加载图片
创建一个信号, 并将该下载任务放入background thread进行
- (RACSignal *)signalForLoadingImage:(NSString *)imageUrl {
RACScheduler *scheduler = [RACScheduler
schedulerWithPriority:RACSchedulerPriorityBackground];
return [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
UIImage *image = [UIImage imageWithData:data];
[subscriber sendNext:image];
[subscriber sendCompleted];
return nil;
}] subscribeOn:scheduler];
}
订阅该信号
[[[self signalForLoadingImage:tweet.profileImageUrl] // 创建信号
deliverOn:[RACScheduler mainThreadScheduler]] // 信号丢入主线程
subscribeNext:^(UIImage *image) {
cell.twitterAvatarView.image = image; // 也会在主线程触发
}];