我在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/