我目前正在JSON
中的viewDidLoad
方法中加载来自UITableViewController
服务的数据。问题是数据需要时间来检索和解析,视图需要时间来创建。
加载此数据的最佳位置在哪里?我假设在创建视图后有一个钩子在某处加载数据。通过这样做,我将能够在最终视图中使用一些UIActivityIndicatorView
。
感谢
答案 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),加上标签和UIActivityIndicator)。在这
方法你也设置了一个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)
您可以打开新视图并向用户显示UIActivityIndicator,以及为他加载新数据的内容。
至于我,这是最好的选择,因为界面仍然负责,用户可以看到你实际做了些什么而app没有被绞死。