我在ViewController类中有一个UITableView。 ViewController类使用自定义的dataController(在AppDelegate中指定)。在dataController类中,我从网络上获取一些JSON,将其解析为NSMutableArray,然后使用该数据填充ViewController中的UITableView。

这一切都很好,除了应用程序启动时会有明显的滞后,因为获取JSON和使用它需要时间。我想在加载此数据时显示带有活动指示器的空UITableView。不幸的是,每当我将dataController类中的代码放入调度队列中时,UITableView都不会填充数据(数据是根据日志加载的)。我所看到的只是一张空白表。

我想我的主要问题是我不知道如何在dataController类中设置队列,然后用该队列中但在另一个类中的数据更新UI。

相关代码:

从dataController类:

- (void)initializeDefaultDataList {
    NSMutableArray *dataList = [[NSMutableArray alloc] init];
    self.masterDataList = dataList;
    dispatch_queue_t myQueue = dispatch_queue_create("name.queue.my", NULL);
    dispatch_async(myQueue, ^{
        NSString *jsonString = [JSONHelper JSONpostString:@"http://webservice/getData"];

        NSError *jsonError = nil;
        //convert string to dictionary using NSJSONSerialization
        NSDictionary *jsonResults = [NSJSONSerialization JSONObjectWithData: [jsonString dataUsingEncoding:NSUTF8StringEncoding]
                                                                    options: NSJSONReadingMutableContainers
                                                                      error: &jsonError];
        if (jsonError) NSLog(@"[%@ %@] JSON error: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), jsonError.localizedDescription);

        NSArray *dataArray = [jsonResults objectForKey:@"d"];

        for (NSString *dataItem in dataArray) {
            [self addDataWithItem:dataItem];
        }
    });
}


来自AppDelegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
    MyMasterViewController *firstViewController = (MyMasterViewController *)[[navigationController viewControllers] objectAtIndex:0];
    MyDataController *aDataController = [[MyDataController alloc] init];
    firstViewController.dataController = aDataController;
    return YES;
}


从ViewController:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    //would this go here?
    dispatch_async(dispatch_get_main_queue(), ^{
        MyObject *objectAtIndex = [self.dataController objectInListAtIndex:indexPath.row];
        [[cell textLabel] setText:objectAtIndex.name];
    });
    return cell;
}


如果您不能告诉我我真的是iOS和Objective C的新手,那么您可以提供的任何帮助或提示将不胜感激。我什至不确定我是否能正确表达我的问题-似乎我想做的事应该不会那么困难。谢谢!

编辑

好的,所以这可能是生命周期问题。刚刚意识到,我在异步块中设置的任何内容都在该块之外为零,至少直到为时已晚才有所作为。这就是为什么永远不要调用cellForRowAtIndexPath的原因-因为传递给UITableView的masterDataList为空。通过初始化进行了测试

__block NSString *s = [[NSString alloc] init];


在块外,然后在块内设置一个值:

s = @"Testing...";


最后应该在该块运行之后NSLogging s的值。但是很明显,由于s为零,因此该块尚未运行。

最佳答案

工作完成后,看来您在做正确的事情以回到主线程上,但是您尚未告诉表视图它需要显示新数据。 [self.tableView reloadData]应该有所帮助。

关于objective-c - 使用单独的DataController类(使用盛大的中央调度)填充ViewController类中的UITableView,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9762809/

10-11 14:36