1

我已经解决了一些 Stack Overflow 问题,但我似乎不知道如何调整我的代码以包含故障块。如何向此代码添加故障块?

+ (void)loginUser:(NSString *)username withPassword:(NSString *)password :(void (^)(BOOL finished))completionBlock {
  NSString *endpoint = @"Users/Login";
  [self postEndpoint:endpoint params:[NSMutableDictionary dictionaryWithObjectsAndKeys:username, @"Username", password, @"Password", nil] completionBlock:^(DollarResponse *response) {
      NSLog(@"%@",response);
    if ([response.result isEqual:[NSNull null]]) {
      [self displayError:response.message];
    } else {
      Login *login = [[Login alloc] initWithDictionary:response.result];
      [self saveLogin:login];
      completionBlock(YES);
    }
}];
     /* loginUser:withPassword:: */
4

2 回答 2

2

如果可能并且适合您的情况,我更喜欢对异步方法使用通用且简单的完成块。没有特殊的“失败”块 - 因为失败案例将由调用站点直接在完成块中处理。请参见下面的示例:

typedef void (^completion_t)(id result);

-(void) loginUser:(NSString *)username 
     withPassword:(NSString *)password 
       completion:(completion_t)completionHandler;

(有关该方法的更好命名,请参见下文)

在您声明的文档中:

如果成功,结果参数返回@"OK",否则返回一个 NSError 对象,其中包含有关错误的详细信息。

(当然,您可能会返回一些不同的东西,并且更适合作为成功的结果)

好吧,那么您可以按如下方式使用它:

[foo loginUser:user withPassword:pass completion:^(id result){
    if (![result isKindOfClass:[NSError class]]) {
        ...
    }
    else {
        NSLog(@"Error: %@", error);
    }
}];

完成处理程序还有无数其他有效且合理的签名:

typedef void (^completion_t)(NSData* data, NSError* error);

显然,这会在成功的情况下返回一个 NSData ,在失败的情况下返回一个 NSError 。文件详细说明。


当您有一个执行异步任务的Operation对象(例如 的子类)时,您可以将不同的处理程序(块)定义为属性由于您的示例处理异步方法,因此没有理由在这里解释,除非您发布一个新的问题。;)NSOperation

编辑:

根据命名约定,我建议如下:

-(void) loginWithUsername:(NSString *)username 
                 password:(NSString *)password 
               completion:(completion_t)completionHandler;
于 2013-11-04T19:04:31.760 回答
2

首先你需要通过你的块。为此定义一个类型很有用:

 typedef void (^MyErrorBlock)(NSString* error);

请注意,您将在该块中将错误作为 a 传递,NSString因为response.message它看起来像一个字符串。虽然通常错误块传递一个NSError.

要将其作为参数传递,您可以执行以下操作:

 -(void)loginUser:(NSString *)username 
     withPassword:(NSString *)password 
     (void (^)(BOOL finished)): completionBlock
                  (MyErrorBlock): errorBlock

然后你可以像你调用你的completionBlock一样调用它,但是你会response.message像这样传递:

 errorBlock(response.message)

您还可以保存指向您的 errorBlock 的指针,然后在需要时调用它。

于 2013-11-04T18:24:27.003 回答