Web服务完成后的完成块?

我在一个名为WebServices的类中实现了一个RESTful API。 我从我的应用程序中的其他类调用此类中的方法,并希望在成功完成Web服务时执行操作。 我有一个完成块作为我的方法头部分的一部分,但不知道我是否正确使用它们,因为应用程序永远不会到达方法调用的完成部分。 这就是我打电话给我的方法:

[services callUnregisterForPushNotifications:savedAccessToken pushToken:savedPushToken completionBlock:^(NSMutableArray *resultsArray) { NSLog(@">>> COMPLETE! <<<"); [self.loadingView removeFromSuperview]; }]; 

我打电话的方法如下所示:

 - (void)callUnregisterForPushNotifications:(NSString *)accessToken pushToken:(NSString *)pushToken completionBlock:(void (^)(NSMutableArray *resultsArray))completion{ NSLog(@"UNREGISTER FOR PUSH CALLED!"); NSLog(@"PUSH TOKEN %@", pushToken); NSString *appendUrl = @"alerts/unregisterpush/"; NSLog(@"APPEND URL %@",appendUrl); NSURL *unregisterUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", BaseURLString, appendUrl]]; NSLog(@"UNREGISTER URL: %@",unregisterUrl); NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:unregisterUrl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0]; [request setHTTPMethod:@"PUT"]; NSString *appendToken = [NSString stringWithFormat:@"Bearer %@", accessToken]; NSLog(@"TOKEN: %@",appendToken); [request addValue:appendToken forHTTPHeaderField:@"Authorization"]; [request addValue:@"application/json, text/plain, */*" forHTTPHeaderField:@"Accept"]; [request addValue:@"application/json;charset=UTF-8" forHTTPHeaderField:@"Content-Type"]; NSString *postString = [NSString stringWithFormat:@"{\"Guid\":\"%@\"}",pushToken]; NSLog(@"POST STRING: %@",postString); [request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]]; NSLog(@"REQUEST %@",request); [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { NSLog(@"UNREGISTER PUSH NOTIFICATIONS RESPONSE: %@", response); NSLog(@"UNREGISTER PUSH NOTIFICATIONS ERROR: %@", error); NSLog(@"UNREGISTER PUSH NOTIFICATIONS DATA: %@", data); NSData *_data = data;// ... whatever NSMutableString *_string = [NSMutableString stringWithString:@""]; for (int i = 0; i < _data.length; i++) { unsigned char _byte; [_data getBytes:&_byte range:NSMakeRange(i, 1)]; if (_byte >= 32 && _byte < 127) { [_string appendFormat:@"%c", _byte]; } else { [_string appendFormat:@"[%d]", _byte]; } } NSLog(@"UNREGISTER PUSH RESPONSE: %@", _string); id obj= [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; if (!obj) { //NSLog(@"REGISTER PUSH NOTIFICATIONS ERROR: %@", error); } else { //NSLog(@"REGISTER PUSH NOTIFICATIONS DATA: %@", obj); //self.accessToken = [obj valueForKey:@"access_token"]; //NSLog(@"ACCESS TOKEN: %@",self.accessToken); } }]; } 

任何build议/意见,将不胜感激,在此先感谢!

在你的else块中,你应该像下面这样调用完成处理程序:

 // [code omitted for brevity] NSLog(@"UNREGISTER PUSH RESPONSE: %@", _string); id obj= [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; if (!obj) { //NSLog(@"REGISTER PUSH NOTIFICATIONS ERROR: %@", error); } else { completionHandler(resultsArray); // add this line to actually call the completion block passed in //NSLog(@"REGISTER PUSH NOTIFICATIONS DATA: %@", obj); //self.accessToken = [obj valueForKey:@"access_token"]; //NSLog(@"ACCESS TOKEN: %@",self.accessToken); } }]; 

还要确保传入的是实际的数组而不是我传递的resultsArray参数。

你基本上正在做的是传递一个函数(或“块”),它不知道什么时候执行(在任何asynchronous任务完成之后你必须自己去做)。 所以你通过你的调用方法的块:

 [services callUnregisterForPushNotifications:savedAccessToken pushToken:savedPushToken completionBlock:^(NSMutableArray *resultsArray) { NSLog(@">>> COMPLETE! <<<"); [self.loadingView removeFromSuperview]; }]; 

包含在大括号中的代码块被传递给callUnregisterForPushNotifications:pushToken:completionHandler:函数,并分配给completionHandler参数,该参数现在包含您在最初调用方法时传入的代码块。 接收completionHandler块的方法负责在asynchronous任务(networking请求)完成后调用它(如您在发布的第一个代码段中所见)。

 completionHandler(resultsArray); 

这样,一旦你的请求完成了( else块),你就可以执行已经传入的完成块了。这实际上意味着“执行我之前传入的代码块,因为现在我们有来自networking操作的数据“。