在主线程中调用GCD块

时间:2013-02-05 08:47:50

标签: iphone objective-c objective-c-blocks

我正在使用以下代码来获取字符串查询的响应。在我的应用程序中有很多查询,我想一次又一次地复制和粘贴此代码

有什么方法可以创建它的实例,传递urlString然后返回响应..

我尝试过创建一个函数 NSObject类中的+(NSString*) myFunc{}但似乎除了主UI线程之外GCD不起作用。我该如何解决这个问题

__block__  NSString *response;

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

    //your server url and request. data comes back in this background thread
    response; = [NSString stringWithContentsOfURL:[NSURL URLWithString:queryString] encoding:NSUTF8StringEncoding error:&err];

    dispatch_async(dispatch_get_main_queue(), ^{
        //update main thread here.
        NSLog(@"%@",response); // NEED TO RETURN THIS

        if (err != nil)
        {
            UIAlertView *alert = [[UIAlertView alloc]initWithTitle: @"Error"
                                                           message: @"An error has occurred."
                                                          delegate: self
                                                 cancelButtonTitle:@"Ok"
                                                 otherButtonTitles:nil];
            [alert show];
            [indicator stopAnimating];
        }
    });
});

1 个答案:

答案 0 :(得分:1)

我会从错误报告中分离出请求处理,使用完成块向调用者提供反馈。

首先定义完成块语义;我们知道我们想要字符串响应和可选的错误描述符:

typedef void (^COMPLETION_BLOCK)(NSString *response, NSString *error);

第二个实现将在后台获取响应然后在主线程中调用完成块的方法。如果您愿意,这可以是某个全局实用程序类中的类方法:

- (void)responseFromURL:(NSURL *)url
        completionBlock:(COMPLETION_BLOCK)completionBlock
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSError *error = nil;
        NSString *response = [NSString stringWithContentsOfURL:url
                                                      encoding:NSUTF8StringEncoding
                                                         error:&error];

        dispatch_async(dispatch_get_main_queue(), ^{
            completionBlock(response, error);
        }
    }
}

最后调用方法:

[someClass responseFromURL:[NSURL URLWithString:queryString]
           completionBlock:^(NSString *response, NSError *error) {

    NSLog(@"response='%@'", response);

    if (error != nil)
    {
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error getting response"
                                                       message:[error localizedDescription]
                                                      delegate:self
                                             cancelButtonTitle:@"Ok"
                                             otherButtonTitles:nil];
        [alert show];
        [indicator stopAnimating];
    }
}];

(此代码未经测试,因此无疑会包含一些错误)

相关问题