在后台重新加载UITableView的数据

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

它的tableView分为3个部分。

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

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

我不使用asynchronous请求,块,线程等…我正在寻找提示。

其实这就是我所做的:

-(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的执行顺序,但是我需要等待这3个函数在刷新我的tableView之前完成。

谢谢你的帮助。

编辑

感谢您的答复。

这是工作解决scheme:

作为mrosbuild议,我从viewDidLoad中删除了调度队列,并在reloadDatas中进行replace:

 dispatch_queue_t concurrentQueue = dispatch_get_main_queue(); 

 dispatch_queue_t mainThreadQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 

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

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

所以你的“后台线程”实际上是你的主线程。 您必须使用dispatch_get_global_queue并指定实际获得不同线程的优先级。 而且,viewDidLoad中的dispatch async是无用的,因为在主线程中调用了所有视图控制器生命周期方法。 我build议你在f1,f2和f3方法中做如下的事情:

首先启动一个asynchronousurl请求,然后在完成块中更新arrayX并重新加载tableview的一个特定部分。 这样,所有三个请求都可以同时发生,并且每个表完成时,表格都会更新必要的数据。 另外,如果你只想重载一次,只需用后台线程replace你所拥有的concurrentQueuevariables,然后在主线程上执行[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 ie 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 }); } 

reloadDatas方法中,你应该改变这一行:

 dispatch_queue_t concurrentQueue = dispatch_get_main_queue(); 

至:

dispatch_queue_t concurrentQueue = dispatch_queue_create("some queue", NULL);

但是当你调用[myDisplayedTable reloadData] ,你需要在主队列中调用这个操作。

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

还有一件事 从服务器拉取数据和更新表格单元是相当普遍的。 这里不需要排队或定时器。 这是另一种结构。

说你从你的服务器拉mp3:你的模型类是:Music.h / m你的模型pipe理器是:MusicManager.h / m(Singleton) – 它将包含一个音乐对象的数组 – 这个单例基本上是你的数据源; 最后是你的UItableViewController:MusicTableVC.h / m

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

在MusicManager里面,你有几个帮助器方法来添加或删除mutableArray中的项目,并提供计数和当然你的networking方法。

最后:在networking代码中发布通知。 您的UITableViewController应该监听/观察该通知并相应地“重新加载”。

  [[NSNotificationCenter defaultCenter] postNotificationName:@"NewMusicAdded" object:nil]; 

您可以从您的服务器查询数据,parsing数据到音乐对象将它们添加到您的NSMutablearrays,并发布通知让表更新自己。

相当标准的食谱。