什么是最好的方式从服务器下载数据并显示在UITableViewController或UIViewController没有被卡住的GUI?
请在投票前先阅读或向我建议STACKOVERFLOW的其他链接。什么是最好的方式从服务器下载数据并显示在UITableViewController或UIViewController没有被卡住的GUI?
有许多结构从服务器下载数据。像
- viewDidLoad中使NSURLConnection的,调用它的代表,当连接结束,使解析器和分析器数据,然后保存到数据库中。 (一切都在同一个类)
另一种方式是
- 做一个单独的类,将管理所有NSURLConnections +的NSXMLParser,只是使该类的对象viewDidLoad中或ViewController类的任何其他方法。
另一种方式是
-
做一个文件来设置连接,并使另一个文件管理解析器
ViewController =====================>> URLConnection Delegate of URLConnectionfile =====================>> ViewController
然后,在此委托,NSData的被下载从服务器进一步发送到Parser类
ViewController =======================>> ParserClass
Delegate of Parser gives Array to ================= ViewController
然后显示该阵列
的另一种方式是使用螺纹
-
呼叫这样的方法在
[自performSelectorInBackground:@selector(doSomething的)withObject:无];
然后在DoSomething的,打电话给你的连接文件
任何人都可以定义下载并保存在一个非常有组织的和适当的方式,最好的方式,使之成为易于管理和无视图挂起发生。
谢谢
不要在主线程上运行你的下载和解析代码。这是唯一的方法以避免UI冻结。
推荐的方式,
-
NSOperation
和NSOperationQueue
- GCD
- 使用第三方框架,如
AFNetworking
,MKNetworkKit
等
另外,如果你有图片在你的表视图,使用称为延迟加载的技术。我建议不要使用[self performSelectorInBackground:@selector(doSomething) withObject:nil];
。如果你不知道如何使用它,那会变得麻烦,而使用GCD。
编辑的处理Web服务
通常情况下,我跟着,
- Webservice的引擎类调用与
NSOperation
和NSOperationQueue
(你可以使用GCD或其他框架)。调用WS的任何视图控制器都将与此类进行通信。 - 解析器类将从Webservice引擎接收WS响应。它将解析响应并创建模型类。完成后,它将解析的响应委托给Webservice引擎,并从这里委托给视图控制器。
- 在Webservice引擎中处理错误处理和进度指示。
-
重要:从视图控制器发出请求的位置,处理发生在由
NSOperationQueue
创建的后台线程上。因此不会冻结UI。
调用WS在viewDidLoad
开始,显示进度指示器直到过程完成。但是有时候要求在下载WS响应之前不会创建视图控制器。因此选择发起请求是基于您的要求。
希望有帮助!
从iOS4 + Apple推出了GCD。见Concurrency Programming Guide: Dispatch Queues
这可能是做异步的东西(特别是webcalls)最好的和最推荐的方式。
例
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSData *responseData = nil;
NSDictionary *responseDictionary = nil;
responseData = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60] returningResponse:&response error:&error];
//Update the UI after this
dispatch_async(dispatch_get_main_queue(), ^{
[self updateUIAfterParsing];
});
});
我的建议是,你可以用GrandCentralDispatch(GCD)去
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
for(NSString *urlString in self.urlArray)
{
NSURL *url=[NSURL URLWithString:urlString];
NSData *data=[NSData dataWithContentsOfURL:url];
UIImage *image=[UIImage imageWithData:data];
//delegate to parse the content/data
//delegate to save data/images into documents directory/DB
}
dispatch_async(dispatch_get_main_queue(), ^{
//UIUpdation, fetch the image/data from DB and update into your UI
});
});
说实话,你很可能没有得到 “最佳途径” 的答案 - 因为这将需要一个相当复杂的解决方案,其中打开了几十个其他子问题,每个问题都值得单独的SO问题。尽管你可能得到的答案是,“快速”解决方案有很多注意事项,只能在温和的条件下工作。 – CouchDeveloper