如何使UIViewController暂停直到数据加载

时间:2014-11-18 02:48:00

标签: ios mysql objective-c multithreading uiviewcontroller

我将UIViewController推到另一个上面,并在其initwithNib中调用一个函数,该函数从通过Internet访问的MySQL数据库加载数据。我将数据库查询的结果存储在一个数组中,并使用该数组中的数据来更改视图上的标签。现在,视图加载了"将文本放在此处"在视图中而不是我想要显示的文本。如何在数据可用后才能加载视图?

这是我的初学者:

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

        if(self){
 ...setting additional irrelevant attributes....
            NSLog(@"running init");
           [self fetchFeed: 0]; <----here is where I grab the online data
            NSLog(@"%@ SELF TOTAL ARRAY", self.totalArray); <-here is where I try to print the data fetched, but actually this array is still empty when printed even though it's full later.

        }

这是从互联网上获取数据的功能:

- (void)fetchFeed: (int) type
{
..code to set the request string....

    NSURL *url = [NSURL URLWithString:requestString];
    NSURLRequest *req = [NSURLRequest requestWithURL:url];

    /*

     NSURLSessionDataTask *dataTask =
     [self.session dataTaskWithRequest:req completionHandler:
     ^(NSData *data, NSURLResponse *response, NSError *error){
*/


    static NSURLSession* sharedSessionMainQueue = nil;
    if(!sharedSessionMainQueue){
        sharedSessionMainQueue = [NSURLSession sessionWithConfiguration:nil delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
    }
    NSURLSessionDataTask *dataTask =
    [sharedSessionMainQueue dataTaskWithRequest:req completionHandler:
     ^(NSData *data, NSURLResponse *response, NSError *error){
        NSMutableArray *jsonObject = [NSJSONSerialization JSONObjectWithData:data
                                                                      options:0
                                                                        error:nil];
         if(type<2) self.totalArray = jsonObject;

        // NSLog(@"json object is %@", jsonObject);
         dispatch_async(dispatch_get_main_queue(), ^{            
           [self updateDisplays];
         });

     }];
    [dataTask resume];
}

这是我在dispatch_async块中调用的函数,用于在数据加载后刷新数据:

- (void)updateDisplays
{

    self.answerArray = [self.totalArray[self.indexLocal] objectForKey:@"answers"];
    self.answerIDArray = [self.totalArray[self.indexLocal] objectForKey:@"answerUser"];
    self.question.text = [self.totalArray[self.indexLocal] objectForKey:@"question"];
    self.questionUser.text = [self.totalArray[self.indexLocal] objectForKey:@"questionUser"];
//    NSLog(@"inside update displays");
}

正如你所看到的,我在默认队列上使用dispatch_async启动了这个,然后切换到主队列,这样可以解决滞后问题,但它并没有。那么如何让数据在显示给用户之前等待数据呢?我已经尝试查看用于多线程运行循环管理的apple开发人员文档,但这似乎超出了我的需要。我在这里缺少什么?

对于后台,我查看了有关同步和异步任务(Understanding dispatch_async)的一些帖子以及如何在从互联网加载数据时在一个合适的视图中管理视图延迟(How to stop UITableView from loading until data has been fetched?) 。这些中的建议(使用主队列或在NSURLSession块结束时重新加载数据)并没有解决我的问题。

2 个答案:

答案 0 :(得分:1)

  1. 您是否考虑过删除UILabel中的“将文字置于此处”,或者至少只是将UILabel的文本设置为空字符串?
  2. 您可以在父视图中对您想要的数据进行HTTP调用,将您的UIViewController推送到导航堆栈,并在您拥有数据时仅显示该视图控制器。如果您打算走这条路线,我建议您在父UI中添加一些加载指示器。

答案 1 :(得分:0)

所以我在这里找到了一个更好的方法: Loading screen for data-intensive view

您可以在放置加载屏幕时生成一段代码以执行您想要的操作。这比留在旧视图并使应用看起来更慢更好。