什么是从服务器下载数据并在UITableViewController或UIViewController中显示而不会卡住其GUI的最佳方式?

时间:2013-09-25 10:49:14

标签: ios objective-c nsurlconnection nsxmlparser viewcontroller

请在投票前阅读或建议我使用STACKOVERFLOW的其他链接。

有许多结构可以从服务器下载数据。喜欢

  1. ViewDidLoad 创建NSURLConnection,调用其委托,当连接结束时,创建解析器和解析器数据,然后保存到DB。 (同类课程中的所有内容)
  2. 另一种方式是

    1. 创建一个单独的类,它将管理所有NSURLConnections + NSXMLParser,只需在 ViewDidLoad 任何其他方法中创建该类的对象< /Con> 的ViewController类。
    2. 另一种方式是

      1. 创建一个文件来设置连接,并创建另一个文件来管理解析器

        ViewController =====================>> URLConnection
        Delegate of URLConnectionfile =====================>> ViewController 
        
      2. 然后,在此委托中,从服务器下载的NSData将进一步发送到Parser类

           ViewController =======================>> ParserClass
          Delegate of Parser gives Array to ================= ViewController
        

        然后显示该数组

        另一种方法是使用线程

        1. 中调用此类方法

          [self performSelectorInBackground:@selector(doSomething)withObject:nil];

        2. 然后在 doSomething 中,调用您的连接文件

          任何人都可以定义以最有条理和最恰当的方式下载和保存的最佳方式,这样就可以轻松管理并且不会出现视图挂起。

          由于

3 个答案:

答案 0 :(得分:1)

不要在主线程上运行下载和解析代码。这是唯一的方法,以避免UI冻结。

推荐方式,

  1. NSOperationNSOperationQueue
  2. GCD
  3. 使用第三方框架,例如AFNetworkingMKNetworkKit等。
  4. 此外,如果您在表视图中有图像,请使用称为延迟加载的技术。

    我建议不要使用[self performSelectorInBackground:@selector(doSomething) withObject:nil];。如果您不知道如何使用它会变得混乱,而不是使用GCD。


    修改

    通常,我关注的是,

    • Webservice引擎类,它使用NSOperationNSOperationQueue处理Web服务调用(您可以使用GCD或其他框架)。任何调用WS的视图控制器都将与该类通信。
    • Parser类将从Webservice引擎接收WS响应。它将解析响应并创建模型类。完成后,它会将解析后的响应委托给Webservice引擎,并从此处委派给视图控制器。
    • 错误处理和进度指示在Webservice引擎中处理。
    • 重要:指向从视图控制器发出请求的位置,处理在NSOperationQueue创建的后台线程上进行。因此不会冻结UI。

    viewDidLoad中启动对WS的调用,并显示进度指示器,直到进程完成。但有些时候要求是在下载WS响应之前不会创建视图控制器。因此,发起请求的选择取决于您的要求。

    希望有所帮助!

答案 1 :(得分:1)

从iOS4 + Apple开始推出GCD。见Concurrency Programming Guide: Dispatch Queues

这可能是做异步内容的最佳和最推荐的方法(尤其是网络连接)。

示例

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]; 
    });

});

答案 2 :(得分:0)

我的建议是,您可以使用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
            });




    });