dispatch_async进入无限循环

时间:2013-04-04 12:00:50

标签: iphone ios uitableview

正在开发一个应用程序,我必须从JSON获取数据并在UITableView中显示。在后台获取数据。但它似乎无限循环。

非常感谢任何帮助。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier   forIndexPath:indexPath];
queue = dispatch_queue_create("com.events.app", NULL);
dispatch_async(queue, ^{
    [self load];
    //Need to go back to the main thread since this is UI related
    dispatch_async(dispatch_get_main_queue(), ^{
        // store the downloaded image in your model
        Events *evObj = [eventsArray objectAtIndex:[indexPath row]];
        NSLog(@"evObj = %@",evObj);
        cell.textLabel.text = evObj.eName;
        cell.detailTextLabel.text = @"Detailed Text";
        [self.tableView beginUpdates];
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil]
                              withRowAnimation:UITableViewRowAnimationLeft];
        [self.tableView endUpdates];
    });
});
    // Configure the cell...



return cell;
}

3 个答案:

答案 0 :(得分:2)

它进入循环,因为发送-reloadRowsAtIndexPaths:withRowAnimation:会触发UITableView向您的数据源询问另一个-tableView:cellForRowAtIndexPath:

的单元格

如果要异步更新单元格,则必须更新直接UI元素,但避免重新加载整个单元格。如果事情没有自动更新,您可以在更新后发送-setNeedsDisplay-setNeedsLayout

答案 1 :(得分:1)

只需删除所有异步调用:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier   forIndexPath:indexPath];

   if(cell == nil) {
     /// load the cell.
   }


    // store the downloaded image in your model
   Events *evObj = [eventsArray objectAtIndex:[indexPath row]];
   NSLog(@"evObj = %@",evObj);
   cell.textLabel.text = evObj.eName;
   cell.detailTextLabel.text = @"Detailed Text";


   return cell;
}

只需将[self load];移至代码的其他部分,例如viewDidLoad

答案 2 :(得分:0)

将数据部分与ui部分区分开来。

只需调用[self load];方法一次,或多次调用您需要的方法。最好的地方是viewDidLoad方法左右。

重新加载数据并在uitableview中显示它们的实现可能看起来像这样(使用GCD)

dispatch_queue_t queue = dispatch_queue_create("com.events.app", NULL);

dispatch_async(queue, ^{
[self load];

//Need to go back to the main thread since this is UI related
dispatch_async(dispatch_get_main_queue(), ^{
    [self.tableview reloadData];

//don't forget to release your queue
dispatch_release(queue);

});

});

从rckoenes复制- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {}方法的实现,你就完成了;)

但请记住一件重要的事情。你的第一个抛出的代码会导致很大的开销,你每次调用这个方法时都要下载,解析和设置数据,当uitableview加载自己时,至少开始3次,然后每次滚动它时都会被调用多次您可以在屏幕上看到许多行/单元格