我是反应性Cocoa的新手并且喜欢这么远。
我创建了一个注册页面。如果用户名和密码有效,我启用注册按钮。对于登录按钮,我执行了以下操作:
[[[[self.registerButton rac_signalForControlEvents:UIControlEventTouchUpInside]
doNext:^(id x) {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
self.registerButton.enabled = NO;
}]
flattenMap:^RACStream *(id value) {
Login *login = [Login new];
return [login registerSignalWithName:self.usernameTextField.text
andPassword:self.passwordTextField.text];
}]
subscribeNext:^(NSDictionary *result) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
// Go to next page
}
error:^(NSError *error) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:error.localizedDescription
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}];
我的问题:如果是用户名已存在我返回错误。但是如果我返回错误,那么registerButton上的rac_signalForControlEvents的订阅将结束!我将不再获得信号,我的registerButton将不再做出反应。根据文档,这是正确的行为。
另一方面:如果我在发生错误时使用sendNext而不是sendError,我在sendNext上会有不同的返回类型(错误或字典会在成功的情况下显示结果)。这也不好。因此,在这种情况下,错误不可用,因为它不允许简单的错误处理。
该问题的正确反应解决方案是什么?
答案 0 :(得分:1)
您可以将catch:
用于此目的。
[[[[self.registerButton rac_signalForControlEvents:UIControlEventTouchUpInside]
doNext:^(id x) {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
self.registerButton.enabled = NO;
}]
flattenMap:^RACStream *(id value) {
Login *login = [Login new];
return [[login registerSignalWithName:self.usernameTextField.text
andPassword:self.passwordTextField.text]
catch:^RACSignal *(NSError *error) {
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle:@"Error"
message:error.localizedDescription
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
return [RACSignal empty];
}];
}]
subscribeNext:^(NSDictionary *result) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
error:^(NSError *error) {}];
catch:
的工作方式与flattenMap:
类似,但catch:
会对错误事件做出反应,而非下一步事件。