如何从iOS中的服务器异步获取数据并在接收数据后更新UI?

时间:2015-07-03 06:27:56

标签: ios objective-c asynchronous grand-central-dispatch

在我的iOS应用中,我正在尝试从服务器获取数据。我想异步这样做。我正在尝试这个:

 - (void)loadData {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

  /** code for fetching data. **/

  dispatch_async(dispatch_get_main_queue(), ^{
    myList = [NSMutableArray arrayWithObjects:fetchedData, nil];
  });
 });


}

上面的方法loadData()是从tableViewController的init()方法调用的。

我使用此列表中对象的数据显示为单元格。 但是在我从服务器接收数据之前,主线程尝试从列表中填充UI(显然是空的)。我如何同步这些?

我发现:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 

上面的函数(返回myList的计数)返回0,因此我的表显示为空。在我从服务器接收数据之前调用此函数(因为这需要更多时间,而此方法立即在主线程中转移控制)。

4 个答案:

答案 0 :(得分:2)

从服务器获取数据后,只需重新加载'你的桌子了。然后 再次调用方法(numberOfRows,numberOfSections,...)。

  

调用此方法重新加载用于构造表的所有数据,包括单元格,节页眉和页脚,索引数组等。为了提高效率,表视图仅重新显示可见的行。如果表因重新加载而缩小,它会调整偏移量。表视图的委托或数据源在希望表视图完全重新加载其数据时调用此方法。它不应该在插入或删除行的方法中调用,尤其是在通过调用beginUpdates和endUpdates实现的动画块中。

检查 https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/index.html#//apple_ref/occ/instm/UITableView/reloadData

 - (void)loadData {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

      /** code for fetching data. **/

      dispatch_async(dispatch_get_main_queue(), ^{
        myList = [NSMutableArray arrayWithObjects:fetchedData, nil];
        yourTable.reloadData()  // <-- reload your table after update myList
      });
     });


    }

答案 1 :(得分:0)

我建议您查看AFNetworkinghttps://github.com/AFNetworking/AFNetworking)。在AFHTTPRequestOperationManager的完成处理程序中,只需设置tableView dataSourcedelegates以及reloadData()。另一种方法是在tableView dataSource setter方法中重新加载数据。

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *stringURL = //ur url;

[manager GET:stringURL parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
    if (completion) {
        //ur completion
    }
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    if (completion) {
        NSLog(@"error: %@", [error localizedDescription]);
    }
}];

答案 2 :(得分:0)

- (void)loadData {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

/** code for fetching data. **/

  dispatch_async(dispatch_get_main_queue(), ^{
    myList = [NSMutableArray arrayWithObjects:fetchedData, nil];
    [yourTable reloadData]; // reload the data

  });
 });


}

答案 3 :(得分:-1)

你可能想在调用你的fetch函数后尝试调用你的loadData函数。在你的场景中,在你获取函数之前首先调用loadData,这就是为什么你总是得到一个空的myList。在调用loadData之前先调用fetch函数。

如果你想使用async,你也可以把你的fetch函数放在异步中,但是要设置一个断点,以便它不会一直调用它。