iOS中的范围和线程

时间:2013-04-23 13:36:00

标签: ios objective-c json nsarray nsdictionary

我对iOS中的Web服务调用和线程都不熟悉。我的应用中有一个ViewController,其中包含一个tableview控件。我使用通过JSON Web服务获得的数据填充表。 JSON Web服务在其自己的线程上调用,在此期间我填充NSArrayNSDictionary

我的数组和字典似乎超出了范围,因为我的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]);
    }
}

3 个答案:

答案 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元素之前打印它们。以下是发生的事情:

  1. 您准备网址
  2. 您创建新线程以获取某个日期。执行此线程可能需要一些时间(取决于连接速度和数据量)。
  3. 当线程正在执行时,您正在访问jsonArray,并且未调用fetchedData:
  4. 另外,建议: 不要使用dataWithContentsOfURL:方法。最好看一下像AFNetworking这样的网络框架。