在UITableView上的GCD实现 [英] GCD implementation on a UITableView

查看:112
本文介绍了在UITableView上的GCD实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我创建单元格时,我正在做一些沉重的计算。我试图找出保持UITableView流体的最好的方法,但在相同的类型做背景上的计算(保持UI线程没有太多的处理)。



仅供测试之用,我将其用作重要的计算方法:

  +(NSString *)bigCalculation 
{
int finalValue = 0;
int j = 0;
int i = 0;

for(i = 0; i <1000; i ++){
for(j = 0; j< 10000000; j ++){
j ++;
}
finalValue + = j / 100 * i;
}

return [NSString stringWithFormat:@%d,finalValue];
}

在cellForRowAtIndexPath内,我只做以下操作:

   - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
NSString * identifier = @identifier;

UITableViewCell * cell = nil;
cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if(!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
}

NSString * text = [dataSource objectForKey:[[dataSource allKeys] objectAtIndex:indexPath.row]];


dispatch_queue_t a_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0);
;
dispatch_async(a_queue,^ {

NSString * subtitle = [CalculationEngine bigCalculation];
dispatch_async(dispatch_get_main_queue(),^ {
[cell detailTextLabel] setText: subtitle];
dispatch_release(a_queue);
});
});


[[cell textLabel] setText:text];
return cell;
}



现在我有UITableView流体,而在后台一切正常好。所以我的问题是:



1)这是最好的方式来实现我想要的,KVO也可以的答案? p>

2)之前:

  dispatch_queue_t a_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0); 

我在做:

  dispatch_queue_create(com.mydomain.app.newimagesinbackground,DISPATCH_QUEUE_SERIAL)

性能非常差。你能解释一下为什么吗?

解决方案

这不是一个好方法。你通过将计算工作推入视图控制器来打破MVC。您应该将数据保存在模型对象中并管理其中的计算。然后,当数据改变时,表视图应该只显示来自模型的当前值,使用 reloadRowsAtIndexPaths:withRowAnimation:。 KVO是确定数据何时更改的一种合理方式。



如果您想在计算中延迟,那么可以调用模型,如 recalculateIfNeeded ,让模型知道有人(在这种情况下是表视图)想要一个新的值。但是,如果输入数据没有实际更改,则不应重新计算。该模型是跟踪数据是否已更改的位置。


I am doing some heavy calculations when I am creating cells. I am trying to figure out the best way to keep the UITableView fluid, but at the same type do the calculations on the background (keep the UI thread without too much processing).

For testing purposes only, I am using this as my heavy calculation method:

+(NSString*)bigCalculation
{
    int finalValue=0;
    int j=0;
    int i=0;

    for (i=0; i<1000; i++) {
        for (j=0; j<10000000; j++) {
            j++;
        }
        finalValue+=j/100*i;
    }

    return [NSString stringWithFormat:@"%d",finalValue];
}

Inside the cellForRowAtIndexPath, I am only doing the following:

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *identifier=@"identifier";

    UITableViewCell *cell=nil;
    cell=[aTableView dequeueReusableCellWithIdentifier:identifier];
    if(!cell)
    {
        cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
    }

    NSString *text=[dataSource objectForKey:[[dataSource allKeys] objectAtIndex:indexPath.row]];


    dispatch_queue_t a_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
;
    dispatch_async(a_queue, ^{

        NSString *subtitle=[CalculationEngine bigCalculation];
        dispatch_async(dispatch_get_main_queue(), ^{
            [[cell detailTextLabel] setText:subtitle];
            dispatch_release(a_queue); 
        });
    });


    [[cell textLabel] setText:text];
    return cell;
}

At the moment I have the UITableView fluid, while in the background everything is working ok. So my questions are:

1) Is this the best way to achieve what I want, could KVO be the answer as well?

2) Before doing this:

dispatch_queue_t a_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);

I was doing:

dispatch_queue_create("com.mydomain.app.newimagesinbackground", DISPATCH_QUEUE_SERIAL)

And the performance was very poor. Could you explain me why?

解决方案

This isn't a good approach. You're breaking MVC here by pushing the calculation work into the view controller. You should keep your data in model objects and manage the calculations there. The table view should then just display the current value from the model, using reloadRowsAtIndexPaths:withRowAnimation: when the data changes. KVO is one reasonable way to determine when the data changes.

If you want to be lazy in calculations, then you can make calls to the model like recalculateIfNeeded to let the model know that someone (the table view in this case) would like a fresh value. You shouldn't recalculate if the input data hasn't actually changed, however. The model is where to keep track of whether the data has changed.

这篇关于在UITableView上的GCD实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆