【发布时间】:2012-07-21 08:15:03
【问题描述】:
您好:我一直在编写一个 iOS 程序,它使用许多对后端 Rails 服务器的 http 查询,因此有大量如下所示的代码。在这种情况下,它正在更新 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.");
问题是:最后一行通常在代码块之前执行。如何确保块后的代码实际在块后运行?
我知道该块使用了一些其他线程,这就是我使用performSelectorOnMainThread 函数而不是直接调用[self.tableView reloadData] 的原因。但是如果我以后想做别的事情,我该怎么做呢?
另外,谁能展示一些更好的方法来做到这一点?我正在尝试找出对后端进行大量调用的最佳方法。有几种方法可以发出异步请求,包括这种阻塞方式和另一种调用委托类的老式方式。在重构代码的过程中,我还尝试创建自己的委托类并让其他类调用它,但是很难确定回调函数针对它返回的连接数据的正确行为,尤其是对于使用多个函数的类调用不同的请求。而且我不想使用同步调用。
非常感谢您的任何回答。也欢迎指出代码中的任何错误。
【问题讨论】:
-
您是否在到达异步块末尾之前看到“函数结束”打印?即在“请求已发送!”之前
-
非常抱歉,我在发布此问题后立即看到了这一点。所以我编辑了它,并在这里继续问其他问题。感谢您的通知。
-
今年 WWDC 的 Session 211 有很多关于使用 NSOperationQueue 实现这种结构的信息,这是一个很棒的演讲。
标签: iphone xcode asynchronous objective-c-blocks nsurlrequest