我对iOS中的Web服务调用和线程都不熟悉。我的应用中有一个ViewController
,其中包含一个tableview控件。我使用通过JSON Web服务获得的数据填充表。 JSON Web服务在其自己的线程上调用,在此期间我填充NSArray
和NSDictionary
。
我的数组和字典似乎超出了范围,因为我的NSLog
语句对于数组计数返回零,即使在fetchedData
中数组已完全填充。
有人可以解释为什么我的数组和字典对象在线程外是空的吗?
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *serviceEndpoint = [NSString stringWithFormat:
@"http://10.0.1.12:8888/platform/services/_login.php?un=%@&pw=%@&ref=%@",
[self incomingUsername], [self incomingPassword], @"cons"];
NSURL *url = [NSURL URLWithString:serviceEndpoint];
dispatch_async(kBgAdsQueue, ^{
NSData *data = [NSData dataWithContentsOfURL:url];
[self performSelectorOnMainThread:@selector(fetchedData:) withObject:data waitUntilDone:YES];
});
NSLog(@"ARRAY COUNT: %d\n", [jsonArray count]);
}
-(void)fetchedData:(NSData*)responseData{
NSError *error;
jsonDict = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
jsonArray = [[jsonDict allKeys]sortedArrayUsingSelector:@selector(compare:)];
for(NSString *s in jsonArray){
NSLog(@"%@ = %@\n", s, [jsonDict objectForKey:s]);
}
}
答案 0 :(得分:0)
当您使用dispatch_async
时,该位代码不会阻止。这意味着在调用fetchedData
之前触发了数组计数日志语句,因此您的字典和数组仍为空。查看日志语句的顺序 - 在记录字典之前应该看到数组计数。
// Executes on another thread. ViewDidLoad will continue to run.
dispatch_async(kBgAdsQueue, ^{
NSData *data = [NSData dataWithContentsOfURL:url];
[self performSelectorOnMainThread:@selector(fetchedData:) withObject:data waitUntilDone:YES];
});
// Executes before the other thread has finished fetching the data. Objects are empty.
NSLog(@"ARRAY COUNT: %d\n", [jsonArray count]);
您需要在数据返回后填写TableView
(即FetchData:
)。
答案 1 :(得分:0)
viewDidLoad中的日志语句应该报告该数组为空,因为此时尚未填充该数组。调用dispatch_async会导致该代码块异步运行,并允许viewDidLoad函数在块之前完成。这就是为什么在viewDidLoad结尾处你的数组中没有任何内容。
答案 2 :(得分:0)
您正在尝试在填充jsonArray元素之前打印它们。以下是发生的事情:
另外,建议: 不要使用dataWithContentsOfURL:方法。最好看一下像AFNetworking这样的网络框架。