0

我对 iOS 中的 Web 服务调用和线程有点陌生。我的ViewController应用中有一个包含 tableview 控件的应用程序。我正在使用通过 JSON Web 服务获得的数据填充表。JSON Web 服务在其自己的线程上调用,在此期间我填充一个NSArrayand 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]);
    }
}
4

3 回答 3

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:)。

于 2013-04-23T13:45:11.567 回答
0

viewDidLoad 中的日志语句应该报告该数组是空的,因为当时它还没有被填充。调用 dispatch_async 会导致该代码块异步运行,并允许 viewDidLoad 函数在该块之前完成。这就是为什么在 viewDidLoad 结束时数组中没有任何内容的原因。

于 2013-04-23T13:45:37.223 回答
0

您正在尝试在填充之前打印 jsonArray 元素的计数。这是发生的事情:

  1. 你准备网址
  2. 您创建新线程来获取某个日期。该线程的执行可能需要一些时间(取决于连接速度和数据量)。
  3. 您正在访问 jsonArray 而线程正在执行和 fetchedData: was not called

另外,建议:不要使用 dataWithContentsOfURL: 方法。最好看看一些网络框架,比如 AFNetworking。

于 2013-04-23T13:47:25.387 回答