异步加载 - UITableView和Firebase [英] Asynchronous loading - UITableView and Firebase

查看:137
本文介绍了异步加载 - UITableView和Firebase的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从Firebase加载列表数据并填充UITableView。虽然我看到从我的firebase实例调用的快照,但它们不会填充表,而本地同步的NSMutableArray会显示内容。如何让我的UITableView等待Firebase数据到达那里?



以下是代码:

   - (void)viewDidLoad 
{
[super viewDidLoad];
句柄= [[NSMutableArray alloc] initWithObjects:@Item No.1,@Item No.2,@Item No.3,@Item No.4,@Item No. 5,@编号6,无];
[self loadDataFromFirebase];
NSLog(@%lu,(unsigned long)[handles count]);
self.sampleTableView.delegate = self;
self.sampleTableView.dataSource = self;
}

- (void)loadDataFromFirebase
{
Firebase * listRef = [[Firebase alloc] initWithUrl:@https://wheresthatfoodtruck.firebaseIO.com/ foodtrucks];
[listRef observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot * snapshot){
NSLog(@%@,snapshot.value);
[句柄addObject:snapshot.value];
}];





$ b

处理打印项目编号,但是如果我删除测试数据,[句柄计数]为零,UITableView的加载速度更快,然后从Firebase获取数据。非常感谢 - 我真的很喜欢Firebase,它是一个很棒的平台,我希望能够通过这个问题。

必须记住所有代码(特别是实时更新的块)是异步的。例如,在原始问题的评论以及解决方案的答案中,代码如下:

$ p $ [self loadDataFromFirebase] ;
[self.sampleTableView reloadData];

...不能从上到下读取;在异步块中被填充的数据(或正被更新的数据)和被调用的 reloadData 之间将存在竞争条件也许单元格连接是不稳定的,或者GCD正在优化一个事物,等等。



Firebase记住的第二件事是事件比如 child_added ,可能永远不会有任何完整的概念 - 数据不断变化和更新是完全可能的。再一次,当一个人期望 reloadData 被调用?马上?第一个孩子之后?最后一个孩子?这样做的含义是,如果添加新数据,即使解决方法也会产生您可能不期待的行为(例如,数据不会显示出来,因为 reloadData

您可以在这里采取的一种方法是在数据更改时直接更新您的视图;所以,你的块会像这样:

pre $ [listRef observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot * snapshot){
NSLog(@%@,snapshot.value);
[句柄addObject:snapshot.value];
[self.sampleTableView reloadData];
}];

另一种方法是使用Firebase专门更新您的内部模型,并使用常规的Objective-C方法(KVO,Notifications,MVC等)来分离您的数据并查看关注点,以便在对模型的直接更改之外重新提交视图。


I'm working on a project that loads list data from Firebase and populates a UITableView. While I see the snapshots being called from my firebase instance, they don't populate the table, while a local synchronous, NSMutableArray shows content. How do I make my UITableView wait for the firebase data to get there?

Here's the code:

   - (void)viewDidLoad
{
    [super viewDidLoad];
    handles = [[NSMutableArray alloc] initWithObjects:@"Item No. 1", @"Item No. 2", @"Item No. 3", @"Item No. 4", @"Item No. 5", @"Item No. 6", nil];
    [self loadDataFromFirebase];
    NSLog(@"%lu", (unsigned long)[handles count]);
    self.sampleTableView.delegate = self;
    self.sampleTableView.dataSource = self;
}

-(void)loadDataFromFirebase
{
    Firebase* listRef = [[Firebase alloc] initWithUrl:@"https://wheresthatfoodtruck.firebaseIO.com/foodtrucks"];
    [listRef observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
        NSLog(@"%@", snapshot.value);
        [handles addObject:snapshot.value];
    }];
}

Handles prints out the Item numbers, but if I remove that test data, [Handles count] becomes zero and the loading of the UITableView is faster then getting the data from Firebase. Much appreciated - I really like Firebase, its a great platform and I hope I can get past this issue.

解决方案

With Firebase you have to keep in mind that all code (and, in particular, the blocks for the realtime updates) is asynchronously. For example, in the original question's comments as well as in the work-around answer, code like this:

[self loadDataFromFirebase];
[self.sampleTableView reloadData];

... can't be read from top to bottom; there will be a race condition between the data being populated (or views being updated) in the asynchronous blocks and the reloadData being called; maybe the cell connection is spotty, or GCD is optimizing for one thing over the other, and so on.

The second thing to keep in mind with Firebase is that for events like child_added there might not ever be any notion of "complete" — it's entirely possible for data to continually be shifting and updating; again, when would one expect reloadData to get called? Right away? After the first child? Last child? The implications of this are that if new data is added, even the work-around is going to yield behavior you're probably not expecting (i.e. it'll appear as if data isn't showing up because reloadData will never get called again.)

One approach you can take here would be to directly update your views as the data changes; so, your block would then look like:

[listRef observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
  NSLog(@"%@", snapshot.value);
  [handles addObject:snapshot.value];
  [self.sampleTableView reloadData];
}];

Another approach might be to use Firebase to exclusively update your internal models and use the regular Objective-C approaches (KVO, Notifications, MVC, etc) to separate your data and view concerns to rerender views outside of direct changes to your models.

这篇关于异步加载 - UITableView和Firebase的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆