变量未在异步调用的块中设置

时间:2012-05-28 05:04:45

标签: ios objective-c-blocks

我有以下代码,它连接到服务器(实际上是我自己的机器),下载一些数据,反序列化它,并将它分配给一个全局变量。

UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
MasterViewController *masterController = [navController.viewControllers objectAtIndex:0]; // masterController is a UITableViewController subclass
NSMutableArray *surveys = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1:8000/testapp/survey-data"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *rep, NSData *d, NSError *err) {
    if(d) {
        NSMutableArray *allSurveys = [NSJSONSerialization JSONObjectWithData:d options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil];
        for(NSMutableArray *item in allSurveys) {
            NSString *title = [item objectAtIndex:[item count] - 1];
            [item removeLastObject];
            Survey *survey = [[Survey alloc] initWithArray:item title:title];
            [surveys addObject:survey];
        }
        masterController.surveys = surveys;


        NSLog(@"%@", [masterController.surveys description]);
    }
}];

不幸的是,它不起作用。正如预期的那样,NSLog()(处理程序块内部)打印出所有数据。显然连接正常。但是,视图不会更新,并且行都是空白的。这是否发生是因为在下载完成后调用了块?我怎么能避免这个?

它似乎也可能是由于在块中设置变量引起的。不过,我查看了Apple的文档,看起来这应该不是问题,因为我通过对masterViewController的引用设置了一个数组。我错了吗?

我应该注意到我尝试重写它以使用[NSURLConnection sendSynchronousRequest:returningResponse:error:,效果很好。但是,如果网络速度很慢或发生故障,同步请求可能是一个糟糕的想法,所以我真的需要异步工作。

2 个答案:

答案 0 :(得分:1)

AsynchronousRequest在UI更新发生时不使用主线程,因此对于UI更新,请使用:

dispatch_async(dispatch_get_main_queue(), ^{ 
    //UI update here    
});

答案 1 :(得分:1)

由于您的视图在获取数据之前已加载,因此您需要在数据到达后在表格视图上调用reloadData

为防止出现其他问题,请确保您在主线程上执行此操作,因为UIKit类不是线程安全的。