何时在UITableViewController中加载数据?

时间:2011-07-26 22:35:36

标签: ios uitableview

我目前正在JSON中的viewDidLoad方法中加载来自UITableViewController服务的数据。问题是数据需要时间来检索和解析,视图需要时间来创建。 加载此数据的最佳位置在哪里?我假设在创建视图后有一个钩子在某处加载数据。通过这样做,我将能够在最终视图中使用一些UIActivityIndicatorView。 感谢

3 个答案:

答案 0 :(得分:6)

最后这里有一个基于注释的解决方案:在viewDidLoad中启动一个线程来获取数据而不会阻塞所有:

- (void) viewDidLoad
{
    dataLoaded = NO;

    [self initSpinner];
    [self launchLoadData];
...
}

-(void)launchLoadData {
    NSLog(@"Launching thread");
    [NSThread detachNewThreadSelector:@selector(loadData) toTarget:self withObject:nil];
}

- (void) loadData {
    dataLoaded = NO;
    NSLog(@" thread launched");
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [self loadDataFromURL:nil];
    dataLoaded = YES;
    [self.tableView reloadData];
    [pool release];
}

- (void)loadDataFromURL:(NSString*)url {
    // start the spinner to show that loading may be time consuming...
    [NSThread detachNewThreadSelector: @selector(spinBegin) toTarget:self withObject:nil];
    JSONLoader *loader = [[JSONLoader alloc] init];
    self.accounts = [loader getAccountsFromURL:@"http://foo/bar/repository.json"];
    [loader release];
    //[NSThread sleepForTimeInterval:3];
    [NSThread detachNewThreadSelector: @selector(spinEnd) toTarget:self withObject:nil];
}

并使用该标志显示或不显示表中的数据。从线程调用时,tableView reloadData将执行其余操作。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (dataLoaded) return [self.accounts count];
    return 0;
}

答案 1 :(得分:1)

我认为您要问的是在UITableView中显示来自Web服务的数据的工作流程。

以下是我的建议:

  • 您的viewDidLoad为您的JSON文件生成NSURLRequest。也 向当前视图添加加载视图(我使用带有UIView的{​​{1}} 黑色bg(0.5 alpha),加上标签和UIActivityIndi​​cator)。在这 方法你也设置了一个BOOL ivar(你需要在你的 标题)将loaded称为NO。

  • 您将NSURLRequest数据汇总为可变数据 数据对象。

  • 当您的NSURLRequest完成后,您将其数据转换为字符串, 并将JSON解析为某种类型的数组(如果你的话,还是字典) 想)。在同一方法中,您删除加载视图,并更改 您的布尔值loaded为YES。然后告诉tableView重新加载 这是数据:[self.tableView reloadData];

这是魔法发生的地方......在你的表格视图方法

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (loaded) return [myArrayOfJSONObjects count];
    return 0; // Will only return 0 if the data is not downloaded
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger row = [indexPath row];

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...
    if (loaded) {
        cell.textLabel.text = [myArrayOfParsedJSONObjects objectAtIndex:row];
        //Anything else you want to set
    }
    else {
        //Do nothing :) - you shouldn't reach this else anyway because your numberOfRows method should stop it
    }
}

答案 2 :(得分:0)

您可以打开新视图并向用户显示UIActivityIndi​​cator,以及为他加载新数据的内容。

至于我,这是最好的选择,因为界面仍然负责,用户可以看到你实际做了些什么而app没有被绞死。