在块内调用方法并尝试重新加载数据崩溃

时间:2014-01-06 14:24:56

标签: ios objective-c uitableview objective-c-blocks parse-platform

我使用parse.com作为后端,我的查询非常慢,所以我试图将其更改为使用块。

基本上,我的查询使用我需要的所有内容填充数组,并且根据if语句,我在块中调用方法,这些方法填充我将在cellForRowAtIndexPath中使用的数组。问题是,当我尝试reloadData内部阻止时,应用程序崩溃了。

以下是代码:

- (void)queryForTable {
    PFQuery *exerciciosQuery = [PFQuery queryWithClassName:@"ExerciciosPeso"];
    [exerciciosQuery whereKey:@"usuario" equalTo:[PFUser currentUser]];
    [exerciciosQuery includeKey:@"exercicio"];

    exerciciosQuery.cachePolicy = kPFCachePolicyCacheElseNetwork;

    [exerciciosQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {

         [self configurarDatas];

         _seriesArray = objects;

            if (_seriesArray.count > 0) {
                NSPredicate *predIniciante = [NSPredicate predicateWithFormat:@"serie contains [cd] %@", @"Ini"];
                NSArray *arrayIniciante = [_seriesArray filteredArrayUsingPredicate:predIniciante];


                NSArray *arrayInicianteApenasSeries = arrayIniciante;
                NSArray *arrayInicianteApenasSeries2 = [arrayInicianteApenasSeries valueForKey:@"serie"];
                NSSet *setInicianteApenasSeries = [NSSet setWithArray:arrayInicianteApenasSeries2];
                NSArray *arrayInicianteCount = [setInicianteApenasSeries allObjects];

                if (arrayInicianteCount.count > 0) {
                    [self popularSeriesInicianteAB];
                // [self.tableView reloadData];


                }
                else if (arrayInicianteCount.count > 8) {

                    [self popularSeriesInicianteC];
                    //   [self.tableView reloadData];

                }
                else {

                    [self popularSeriesAvancado];
                    //   [self.tableView reloadData];
                    NSLog(@"POPULAR SERIES AVANÇADO");
                }
            }
    }];

}

我还尝试使用dispatch_async(dispatch_get_main_queue(), ^{ [myDisplayedTable reloadData]; });重新加载数据,但它也没有用。

无论如何,我想如果我擦除我的方法并将所有内容都放在块中,它会起作用,但我不想这样做,因为使用if调用方法会使我的代码更容易理解。

更新:

为了完整性,这是我的DataSource方法:

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
     {
     NSLog(@"numberOfRowsInSection %li", (unsigned long)_seriesForDisplay.count);
     return _seriesForDisplay.count;

 }


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
    static NSString *CellIdentifier = @"Cell";

    PFTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[PFTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }





    PFObject *o = _seriesForDisplay[indexPath.row];
    // Texto da célula
    cell.textLabel.text = o[@"serieDisplay"];

    cell.detailTextLabel.text = o[@"grupos"];



    return cell;

}

3 个答案:

答案 0 :(得分:2)

使用Parse SDK在tableview中实现数据有两种方法

  1. PFqueryTableViewController:你需要实现

    - (PFQuery *)queryForTable {
         return query;
      }
    
    - (PFObject *)objectAtIndex:(NSIndexPath *)indexPath {
      // overridden, since we want to implement sections
      }
    
     - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: 
       (NSIndexPath *)indexPath object:(PFObject *)object {
      //get data: object
      }
    
     - (UITableViewCell *)tableView:(UITableView *)tableView cellForNextPageAtIndexPath:
     (NSIndexPath *)indexPath 
    
  2. UIViewController中的UITableViewController / UITableview:
    这是正常的方法,实现uitableview delegate / datasource,你可以在这里写一个类似(void)queryForTable的方法并调用reloadData。

答案 1 :(得分:2)

我使用的是PFQueryTableViewController,它来自parse.com后端并且有一些不同的方法。我将查询更改为void并使用findObjectsInBackgroundWithBlock。因此,我的方法- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object未收到PFObjects,这就是我在尝试reloadData时遇到崩溃的原因。

我将表格改回UITableViewController

我在块内使用dispatch_async(dispatch_get_main_queue(), ^{ [self.tableView reloadData]; });并且它现在正在运行。

这篇文章很好的答案对我帮助很大。

答案 2 :(得分:1)

如果你不能保证一个块将在哪个线程上运行(如果它可以在后台线程上运行),那么你应该在操作任何UI更改之前切换到主线程。这可以通过performSelectorOnMainThread:withObject:waitUntilDone:dispatch_async(dispatch_get_main_queue(), ^{完成。