在块内返回BOOL方法?

时间:2015-04-22 17:28:13

标签: ios objective-c afnetworking grand-central-dispatch

我有这个bool方法,对输入的字符串返回yes或no。 我已成功返回YESNO,但我似乎无法建立网络连接并返回YESNO,具体取决于服务器的响应。 我尝试使用__block,我觉得不会等待网络请求完成,有没有办法在成功模块中返回YESNO而不给我错误:

  

不兼容的块指针类型将'BOOL(^)(NSURLSessionTask * __ strong,NSError __ strong'发送到'void(^)类型的参数(NSURLSessionTask ...)

-(BOOL)customResponseForString:(NSString *)text {

  __block BOOL response_available;

  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [manager.responseSerializer setAcceptableContentTypes:[NSSet setWithObject:@"text/plain"]];
    [manager GET:[NSString stringWithFormat:@"http://example.com/response.php?input=%@", text] parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {

        NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject options:NSUTF8StringEncoding error:nil];
        response_available = (BOOL)response[@"response_available"];
        if (response_available) {
            [session sendTextSnippet:response[@"response"] temporary:NO scrollToTop:NO dialogPhase:@"Summary"];
        } else {
            response_available = NO;
        }

        [session sendTextSnippet:[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding] temporary:NO scrollToTop:NO dialogPhase:@"Summary"];

        [session sendRequestCompleted];

    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        //return NO;
    }];
 });

return response_available;

}

2 个答案:

答案 0 :(得分:1)

您的块定义语法可能是错误的,因为您肯定可以在块中的其他参数中返回BOOL。

#include <iostream>

using namespace std;

void oddEven( int num ) //My Function  
{ 
    if (num % 2)
    {
        cout << "It's odd" << endl;
    }
    else
    {
        cout << "It's even" << endl;
    }    
}

int main() //Main program    
{        
    int num;
    cout << "Please enter a number " << endl;
    cin >> num;
    oddEven(num); //Calling my Function
    return 0;
}

这个方法会像这样调用:

- (void)fetchCurrentUserWithCompletion:(void (^)(BOOL success, User *user))completion;

如果您使用AFNetworking,请检查处理completionBlocks的[self.userProfileController fetchCurrentUserWithCompletion:^(BOOL success, User *user) { if (success) { NSLog(@"Current User Name: %@", user.fullName); } }]; 对象:

AFHTTPRequestOperation

答案 1 :(得分:1)

因为您隐式初始化response_availableNO然后使用异步GCD调用,所写的方法将始终立即返回NO,而不等待请求完成。注意:切换到dispatch_sync也不会有帮助,因为AFNetworking将以任何方式异步排队GET请求。

最佳方法

customResponseForString:添加完成块参数。然后只需在AFHTTPRequestOperation的成功或失败块中执行完成块。

可行方法(谨慎使用!)

可以使customResponseForString:等待对网络请求的响应,但如果从主线程调用它,则会出现重大问题。

首先,您创建一个调度组并告诉它您正在开始一些长期运行的工作:

dispatch_group_t networkGroup = dispatch_group_create();
dispatch_group_enter(networkGroup);

然后,您需要发出网络请求,并在完成后告诉小组该工作已完成dispatch_group_leave()

[manager GET:[NSString stringWithFormat:@"http://example.com/response.php?input=%@", text] parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {

    NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject options:NSUTF8StringEncoding error:nil];
    response_available = (BOOL)response[@"response_available"];
    if (response_available) {
        [session sendTextSnippet:response[@"response"] temporary:NO scrollToTop:NO dialogPhase:@"Summary"];
    } else {
        response_available = NO;
    }

    [session sendTextSnippet:[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding] temporary:NO scrollToTop:NO dialogPhase:@"Summary"];

    [session sendRequestCompleted];

    dispatch_group_leave(networkGroup);

} failure:^(NSURLSessionDataTask *task, NSError *error) {
    response_available = NO;
    dispatch_group_leave(networkGroup);
}];

在原始方法返回之前,告诉它等待整个组完成处理:

dispatch_group_wait(networkGroup, DISPATCH_TIME_FOREVER);
return response_available;

您可以根据需要调整此时间间隔,或将其保留在DISPATCH_TIME_FOREVER,让网络自行请求超时。