我在ViewController类中有一个UITableView。 ViewController类使用自定义的dataController(在AppDelegate中指定)。在dataController类中,我从Web中获取一些JSON,将其解析为NSMutableArray,然后使用该数据在ViewController中填充UITableView。从独立的DataController类使用宏中央调度在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;
}
从视图控制器:
- (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是零。
我想,在视图控制器,但它可能不在正确的位置。那会在viewDidLoad方法,cellForRowAtIndexPath方法或其他地方完成吗? – esvendsen 2012-03-19 00:19:14
+1为reloadData提示。虽然这不是我的问题的完整答案,但它绝对是不可或缺的。 – esvendsen 2012-03-27 12:46:53