Iphone Xcode,确保块之后的代码稍后运行,以用于NSURLConnection异步请求

Iphone Xcode,确保块之后的代码稍后运行,以用于NSURLConnection异步请求,iphone,xcode,asynchronous,objective-c-blocks,nsurlrequest,Iphone,Xcode,Asynchronous,Objective C Blocks,Nsurlrequest,您好:我一直在编写一个iOS程序,它使用许多http查询到后端rails服务器,因此有很多代码如下。在这种情况下,它正在更新UITableView: //making requests before this... NSOperationQueue* queue = [[NSOperationQueue alloc] init]; [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NS

您好:我一直在编写一个iOS程序,它使用许多http查询到后端rails服务器,因此有很多代码如下。在这种情况下,它正在更新
UITableView

//making requests before this...
NSOperationQueue* queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse* response, NSData* data, NSError* error)
{
    NSLog(@"Request sent!");

    NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
    NSLog(@"Response code: %d", [httpResponse statusCode]);
    if ([data length] > 0 && error == nil){
        NSLog(@"%lu bytes of data was returned.", (unsigned long)[data length]); }
    else if ([data length] == 0 &&
             error == nil){
        NSLog(@"No data was returned.");
    }
    else if (error != nil){
        NSLog(@"Error happened = %@", error); }

    id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
    if (jsonObject != nil && error == nil){
        NSLog(@"Successfully deserialized...");
        if ([jsonObject isKindOfClass:[NSDictionary class]]){
            NSDictionary *deserializedDictionary = (NSDictionary *)jsonObject;
            NSLog(@"Dersialized JSON Dictionary = %@", deserializedDictionary);
            [listOfItems addObject:deserializedDictionary];
        }
        else if ([jsonObject isKindOfClass:[NSArray class]]){
            NSArray *deserializedArray = (NSArray *)jsonObject; 
            NSLog(@"Dersialized JSON Array = %@", deserializedArray);
            [listOfItems addObjectsFromArray:deserializedArray];
        }
        else {
            /* Some other object was returned. We don't know how to deal
             with this situation as the deserializer only returns dictionaries
             or arrays */ }
    }
    else if (error != nil){
        NSLog(@"An error happened while deserializing the JSON data., Domain: %@, Code: %d", [error domain], [error code]); 
    }
    [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
}];
//the place where never runs
NSLog(@"End of function.");
问题是:最后一行通常在代码块之前执行。如何确保代码在块之后实际运行

我知道该块使用了一些其他线程,这就是为什么我使用
performselectornmainthread
函数而不是直接调用
[self.tableView reloadData]
的原因。但是如果我以后想做别的事情,我该怎么做呢

还有,有人能展示一些更好的方法吗?我正试图找出最好的方法,使大量的电话后端。有几种方法可以发出异步请求,包括这种块方法和另一种调用委托类的老式方法。在重构代码的过程中,我还尝试创建自己的委托类,并让其他类调用该委托类,但很难确定它为哪个连接返回数据的回调函数的正确行为,特别是对于使用多个函数调用不同请求的类。我不想使用同步调用


非常感谢您的回答。还欢迎指出代码中的任何错误。

您可以使用dispatch group

示例代码:

- (void)doSomethingAndWait {
// synchronous method
// called in main thread is not good idea.
NSAssert(! [NSThread isMainThread], @"this method can't run in main thread.");

dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);

//making requests before this...
NSOperationQueue* queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse* response, NSData* data, NSError* error)
{
    // your work here.


    dispatch_group_leave(group);
}];

// wait for block finished
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_release(group);

//will call until block is finished.
NSLog(@"End of function.");
}
要调用该方法,需要避免在主线程中调用它

你应该这样称呼它

dispatch_queue_t queue = dispatch_queue_create("com.COMPANYNAME.APPNAME.TASKNAME", NULL);
    dispatch_async(queue, ^{
        [self doSomethingAndWait];
    });

您是否看到“函数结束”在到达异步块结束之前打印?i、 在“请求已发送”之前,非常抱歉,我在发布此问题后立即看到。所以我编辑了它,并在这里继续问其他问题。感谢您的通知。今年WWDC的第211次会议有很多关于使用NSOperationQueue实现这种结构的信息,这是一次很好的讨论。谢谢。看起来很有用。我尝试了另一种方法,在异步块中使用同步请求,使重构更容易。食谱(猫书)也给出了这样一个例子。对于第1种方法,由于该处理程序,在我自己的类中调用它有点困难,因为我希望普遍返回响应数据。这是唯一的办法吗?