1

我需要下载 JSON 并在 iOS5 的后台处理它,所以我不会冻结我的主线程。我这样做没有任何成功。

这是我正在做的事情:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{

    NSURL *url = [NSURL URLWithString:myURL];
    myData = [NSData dataWithContentsOfURL:url];

    [self performSelectorOnMainThread:@selector(processTheData:)
                           withObject:myData
                        waitUntilDone:YES];
}); 

-(void)processTheData:(NSData *)data
{
    //Parse JSON here
}

在上面的代码中,一旦下载完成,我会在 Main thrd 上处理它。当我知道我得到数据时,如何在后台运行它?

4

1 回答 1

7

典型的模式是:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{

    NSURL *url = [NSURL URLWithString:myURL];
    myData = [NSData dataWithContentsOfURL:url];

    dispatch_async(dispatch_get_main_queue(), ^{
        [self processTheData:myData];
    });
}); 

或者,假设它processTheData本身不进行 UI 更新,但您希望在完成后这样做,典型的方法是在需要更新用户界面之前不分派回主队列:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{

    NSURL *url = [NSURL URLWithString:myURL];
    myData = [NSData dataWithContentsOfURL:url];

    [self processTheData:myData];

    dispatch_async(dispatch_get_main_queue(), ^{
        // code that updates UI goes here
    });
}); 

最后,如果您对上述代码进行少量调用,那很好,但如果您可能会执行大量请求,您应该知道许多服务器限制了它们将接受的并发请求的数量从给定的客户。即使服务器没有,您也确实想限制您对服务器发出的并发请求数。如果您使用NSOperationQueue而不是 GCD,您可以轻松地做到这一点。

因此,如果您正在执行多个异步请求,您可能需要执行以下操作(使用第二个示例作为模型)。首先,在您开始发起请求之前,您应该创建一个NSOperationQueue对象:

@property (nonatomic, strong) NSOperationQueue *queue;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.queue = [[NSOperationQueue alloc] init];
    self.queue.maxConcurrentOperationCount = 4;
}

然后,您必须执行单个异步请求的代码将:

[self.queue addOperationWithBlock:^{

    NSURL *url = [NSURL URLWithString:myURL];
    myData = [NSData dataWithContentsOfURL:url];

    [self processTheData:myData];

    [[NSOperationQueue mainQueue] addOperationWithBlock:{
        // code that updates UI goes here
    }];
}]; 
于 2013-01-26T16:52:21.603 回答