在后台重新加载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,并发布通知让表更新自己。
相当标准的食谱。
- 何时在应用程序中调用completionHandler:performFetchWithCompletionHandler:当背景获取是asynchronous?
- 在下一次运行循环中执行:GCD有什么错误?
- 为什么Objective-C / Swift中的asynchronousnetworkingtesting困难?
- 查看与多个DispatchQueue.main.async使用冻结
- Swift:主界面冻结即使一切都在asynchronous线程? URLsession?
- NSURLConnection sendAsynchronousRequest无法从闭包中获取variables
- IOS我如何asynchronous下载和caching图像和video在我的应用程序中使用
- 从asynchronousWeb服务响应更新托pipe对象的最佳方法?
- NSOperationqueue背景,下载图片