Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/110.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在后台重新加载UITableView的数据_Ios_Asynchronous_Uitableview - Fatal编程技术网

Ios 在后台重新加载UITableView的数据

Ios 在后台重新加载UITableView的数据,ios,asynchronous,uitableview,Ios,Asynchronous,Uitableview,在我的应用程序中,我有一个UITableViewController 其tableView分为3个部分 我从服务器上下载每个部分的数据。为此,我有3个函数(例如f1、f2和f3)。每个都更新一个对应的NSArray,用作我的表的数据源 现在,我想要的是使用此函数重新加载数据,并在完成这3个函数后刷新我的tableView,但不会干扰用户 我不使用异步请求、块、线程等。。。我在找小费 实际上,我是这样做的: -(void)viewDidLoad { //some settings

在我的应用程序中,我有一个UITableViewController

其tableView分为3个部分

我从服务器上下载每个部分的数据。为此,我有3个函数(例如f1、f2和f3)。每个都更新一个对应的NSArray,用作我的表的数据源

现在,我想要的是使用此函数重新加载数据,并在完成这3个函数后刷新我的tableView,但不会干扰用户

我不使用异步请求、块、线程等。。。我在找小费

实际上,我是这样做的:

-(void)viewDidLoad
{
    //some settings

    [NSTimer scheduledTimerWithTimeInterval:15.0 target:self selector:@selector(reloadDatas) userInfo:nil repeats:YES];

    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_async(queue, ^{
        [self reloadDatas];
    });
}

-(void)reloadDatas
{
    dispatch_queue_t concurrentQueue = dispatch_get_main_queue();
    dispatch_async(concurrentQueue, ^{
        [self f1];
        [self f2];
        [self f3];
        [myDisplayedTable reloadData];
    });
}

-(void)f1
{
    //load datas with a url request and update array1
}
-(void)f2
{
    //load datas with a url request and update array2
}
-(void)f3
{
    //load datas with a url request and update array3
}
但是在这里,我的tableView在刷新之前是“冻结”的

我不关心f1、f2和f3的执行顺序,但在刷新tableView之前,我需要等待这3个函数完成

谢谢你的帮助

编辑

谢谢你的回答

以下是工作解决方案:

作为mros,我从viewDidLoad中删除了调度队列,并替换为ReloadData:

dispatch_queue_t concurrentQueue = dispatch_get_main_queue();

最后,我在主线程中重新加载我的表

dispatch_async(dispatch_get_main_queue(), ^{ [myDisplayedTable reloadData]; });

reloadDatas
方法中,您应该更改此行:

dispatch_queue_t concurrentQueue = dispatch_get_main_queue();
致:

dispatch\u queue\t concurrentQueue=dispatch\u queue\u create(“某些队列”,NULL)

但是,当您调用
[myDisplayedTable reloadData]
时,需要在主队列中调用此操作

dispatch_async(dispatch_get_main_queue(), ^{ [myDisplayedTable reloadData]; });
所以你的“背景线程”实际上是你的主线程。您必须使用dispatch\u get\u global\u queue并指定优先级才能实际获取不同的线程。此外,viewDidLoad中的dispatch async是无用的,因为所有视图控制器生命周期方法都是在主线程中调用的。我建议您在f1、f2和f3方法中执行以下操作:


首先启动异步url请求,然后在完成块中更新arrayX并重新加载tableview的特定部分。这样,所有三个请求都可以同时发生,并且当每个请求完成时,表只更新必要的数据。或者,如果您只想重新加载一次,只需用后台线程替换您的concurrentQueue变量,然后在主线程上执行
[tableView reloadData]

前面的答案绝对正确。然而,您的reloadDatas&viewDidLoad的实现有点问题

我想澄清一下:

您希望在后台线程中完成耗时的数据加载工作,然后在主线程上的数据就绪后更新UI/单元格

像这样:

  -(void)viewDidLoad
    {
       dispatch_queue_t concurrentQueue = dispatch_queue_create("com.my.backgroundQueue", NULL);
        dispatch_async(concurrentQueue, ^{
            [self reloadDatas];
        });
    }

-(void)reloadDatas
{
    // Expensive operations i.e pull data from server and add it to NSArray or NSDictionary
      [self f1];
      [self f2];
      [self f3];

    // Operation done - now let's update our table cells on the main thread  

    dispatch_queue_t mainThreadQueue = dispatch_get_main_queue();
    dispatch_async(mainThreadQueue, ^{

        [myDisplayedTable reloadData]; // Update table UI
    });
}

还有一件事。从服务器中提取数据并更新表单元格是非常常见的。 这里不需要排队或计时。 这是另一种结构

假设您正在从服务器中提取mp3: 你的模范班是:Music.h/m 您的模型管理器是:MusicManager.h/m(Singleton)——它将包含一系列音乐对象——Singleton基本上是您的数据源; 最后是UItableViewController:MusicTableVC.h/m

在MusicManager.h/m中:您有一个NSMutableArray,它将加载从服务器中提取的Music.h对象。您可以在应用程序加载后立即执行此操作,而无需等待TableViewController

在MusicManager中,您可以使用一些辅助方法从可变数组中添加或删除项,并提供计数,当然还有您的网络方法

最后:在网络代码中发布通知。UITableViewController应该侦听/观察该通知,并相应地“重新加载”

 [[NSNotificationCenter defaultCenter] postNotificationName:@"NewMusicAdded" object:nil];
您可以从服务器查询数据,将数据解析为音乐对象,并将其添加到NSMutable数组中,然后发布通知,让表自行更新


相当标准的配方

我已经尝试过你的解决方案,但是用户交互和重新加载是相互阻碍的。我的意思是,由于用户没有停止滚动表格,因此不会调用重载数据,并且在表格未刷新时,用户无法滚动表格……您确定不会调用重载数据,因为用户正在滚动表格吗?尝试添加一些NSLog或断点。是的,这就是我所说的
用户交互
:滚动表格时,我的NSTimer在滚动结束之前不会调用我的函数。为什么要首先使用计时器?我为您添加了另一个答案,这很有帮助!谢谢你创建了concurrentQueue吗?
 [[NSNotificationCenter defaultCenter] postNotificationName:@"NewMusicAdded" object:nil];