Iphone 如何正确使用GCD在后台线程上执行长进程,在maion线程上执行UI进程/更新

Iphone 如何正确使用GCD在后台线程上执行长进程,在maion线程上执行UI进程/更新,iphone,ipad,grand-central-dispatch,Iphone,Ipad,Grand Central Dispatch,我正在处理这段代码,因为它阻止了时间分析器报告的主线程 OrderModule *module = [OrderModule sharedModule]; for(Modifier *modifier in modifierLists) { int merge = [module getModifierMergeOption:modifier.mModifierId productId:product.mProductId];//long process database interac

我正在处理这段代码,因为它阻止了时间分析器报告的主线程

OrderModule *module = [OrderModule sharedModule];
for(Modifier *modifier in modifierLists)
{
    int merge = [module getModifierMergeOption:modifier.mModifierId productId:product.mProductId];//long process database interaction

    for(ModifierItem *mod_product in modifier.activeModifiers)
    {
        NSString *modifierProductName = mod_product.productName;
        if (merge == 1) {

            modifierProductName = [modifierProductName stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%@ - ",product.mProductName] withString:@""];
        }

        numberOfModifiers++;
        UILabel *modifierNameLabel = [[UILabel alloc] init];
        //            [modifierNameLabel setBackgroundColor:[UIColor redColor]];
        modifierNameLabel.lineBreakMode = UILineBreakModeWordWrap;
        modifierNameLabel.numberOfLines = 0;
        modifierNameLabel.lineBreakMode = NSLineBreakByWordWrapping;
        modifierNameLabel.numberOfLines = 0;
        [modifierNameLabel setFont:DEFAULT_FONT(DEFAULT_FONTSIZE_MODIFIERNAME)];
        modifierNameLabel.textColor = [UIColor colorWithRed:125.0f/255.0f green:127.0f/255.0f blue:131.0f/255.0f alpha:1.0f];
        //            modifierNameLabel.frame = CGRectMake(x, y, 140, 35);
        modifierNameLabel.frame = CGRectMake(x, y, 120, 35);

        modifierNameLabel.text = modifierProductName;
        [orderDetailRow addSubview:modifierNameLabel];


        UILabel *modifierAmount = [[UILabel alloc] init];
        [modifierAmount setFont:DEFAULT_FONT(DEFAULT_FONTSIZE_MODIFIERNAME)];
        modifierAmount.textColor = [UIColor colorWithRed:125.0f/255.0f green:127.0f/255.0f blue:131.0f/255.0f alpha:1.0f];
        //            modifierAmount.frame = CGRectMake(CGRectGetMaxX(modifierNameLabel.frame)+30, y, 100, 35);
        modifierAmount.frame = CGRectMake(CGRectGetMaxX(modifierNameLabel.frame)+6, y, 100, 35);

        [orderDetailRow addSubview:modifierAmount];

        //                modifiersCount++;

        amountPrice=amountPrice+([mod_product.mExtraCost floatValue]*count);
        [modifierAmount setText:[Utils currencyWithSymbol:[NSString stringWithFormat:@"%.02f",(([mod_product.mExtraCost floatValue]*count)+ 0.00001)]]];//simple manipulation

        if ([mod_product.mExtraCost floatValue]<=0) { //3.0 changes
            [modifierAmount setHidden:YES];
        }

        y = y + 25;

    }
    numberOfModifiers++;

}

[self setUpActiveModifierWithX:x andy:y Row:orderDetailRow andModifierList:modifierLists andProduct:product];
OrderModule*module=[OrderModule-sharedModule];
用于(修饰符列表中的修饰符*修饰符)
{
int merge=[module getModifierMergeOption:modifier.mModifierId productId:product.mpProductId];//长进程数据库交互
用于(modifier.activeModifiers中的ModifierItem*mod_产品)
{
NSString*modifierProductName=mod\u product.productName;
如果(合并==1){
modifierProductName=[modifierProductName stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@“%@-”,product.mpProductName]with String:@“”;
}
numberOfModifiers++;
UILabel*modifierNameLabel=[[UILabel alloc]init];
//[modifierNameLabel setBackgroundColor:[UIColor redColor]];
modifierNameLabel.lineBreakMode=UILineBreakModeWordWrap;
modifierNameLabel.numberOfLines=0;
modifierNameLabel.lineBreakMode=NSLineBreakByWordWrapping;
modifierNameLabel.numberOfLines=0;
[modifierNameLabel setFont:DEFAULT_FONT(DEFAULT_FONTSIZE_MODIFIERNAME)];
modifierNameLabel.textColor=[UIColor COLOR WITH RED:125.0f/255.0f green:127.0f/255.0f blue:131.0f/255.0f alpha:1.0f];
//modifierNameLabel.frame=CGRectMake(x,y,140,35);
modifierNameLabel.frame=CGRectMake(x,y,120,35);
modifierNameLabel.text=modifierProductName;
[orderDetailRow addSubview:modifierNameLabel];
UILabel*modifierAmount=[[UILabel alloc]init];
[modifierAmount setFont:DEFAULT_FONT(DEFAULT_FONTSIZE_MODIFIERNAME)];
modifierAmount.textColor=[UIColor COLOR WITH RED:125.0f/255.0f green:127.0f/255.0f blue:131.0f/255.0f alpha:1.0f];
//modifierAmount.frame=CGRectMake(CGRectGetMaxX(modifierNameLabel.frame)+30,y,100,35);
modifierAmount.frame=CGRectMake(CGRectGetMaxX(modifierNameLabel.frame)+6,y,100,35);
[orderDetailRow addSubview:modifierAmount];
//修饰符计数++;
amountPrice=amountPrice+([mod_product.mExtraCost floatValue]*计数);
[ModifierMount setText:[Utils currencyWithSymbol:[NSString stringWithFormat:@“%.02f”,([mod_product.mExtraCost floatValue]*count)+0.00001)];//简单操作

如果([mod_product.mExtraCost floatValue]我会从您正在做的事情中退一步,学习如何使用TableViewController或CollectionViewController


您似乎正在创建大量的子视图,这是一个昂贵的操作。表视图和集合视图通过反复重复使用相同的视图,只是显示不同的值来避免这种情况。您使用的不是昂贵的视图,而是更便宜的单元格。您还自动只处理实际可见的内容,因此如果您有一千项,只有屏幕上的十几项需要CPU时间。

最简单的修复方法是将它放在主线程上执行的块中的最后一条语句之后:

编辑

下面的方法行不通,不幸的是,如果不使用第三个部分库,就没有“轻松修复”方法。我在这里留下答案,以演示异步问题如何快速变得更复杂

-(void)setUpModifierWithX:(float)x andy:(float)y Row:(OrderDetailRow *)orderDetailRow andModifierList:(NSMutableArray *)modifierLists andProduct:(Product *)product
{
    OrderModule *module = [OrderModule sharedModule];
    float __block Y = y;
    for(Modifier *modifier in modifierLists)
    {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

            int merge= [module getModifierMergeOption:modifier.mModifierId productId:product.mProductId];

            dispatch_async(dispatch_get_main_queue(), ^
            {
                for(ModifierItem *mod_product in modifier.activeModifiers)
                {
                   ...
                }
                numberOfModifiers++;


               [self setUpActiveModifierWithX:x andy:y Row:orderDetailRow andModifierList:modifierLists andProduct:product];
            });
        });
    }
}

事实证明,这项看似简单的任务实际上并不那么简单。如果不求助于第三方库,我就无法找到比下面更简单的解决方案,因为第三方库使这类任务更容易(稍后我将使用实用程序库提出解决方案)

这是一种使用递归块的方法

警告

递归块是很棘手的,我不建议使用它们,除非您知道为什么以及如何应用这种技术

代码片段显示了主要的方法,但是您的原始问题需要调整

你的方法

-(void)setUpModifierWithX:(float)x andy:(float)y Row:(OrderDetailRow *)orderDetailRow andModifierList:(NSMutableArray *)modifierLists andProduct:(Product *)product
现在成为异步方法:


关于递归块,请参见下面的问题和答案:

然后它将被执行n次,请参见上面的代码位于for循环中,,thanx@Alok你是对的,这是行不通的。我提出了另一个解决方案,不过看起来确实很简单……补充了另一个答案。
-(void)setUpModifierWithX:(float)x andy:(float)y Row:(OrderDetailRow *)orderDetailRow andModifierList:(NSMutableArray *)modifierLists andProduct:(Product *)product
-(void) foo
{
    NSArray* array = @[@"a", @"b", @"c"];  // your input array, e.g. "modifierLists"

    NSMutableArray* marray = [array mutableCopy]; // we need a mutable array here

    typedef void (^completion_t)(id result);
    typedef void (^block_t)(NSMutableArray*, completion_t);

    // setting up block variable suitable for using that block recursively:
    __block __weak block_t weak_block;
    block_t block;
    weak_block = block  = ^(NSMutableArray*array, completion_t completion) {

        // Check the termination condition for the "loop"
        if ([array count] == 0) {
            if (completion) {
                completion(@"Finished");
            }
            return;
        }
        id item = array[0]; 
        [array removeObjectAtIndex:0];
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            // process "item" on a secondary thread (private queue):
            int merge = [item characterAtIndex:0]; //[module getModifierMergeOption:modifier.mModifierId productId:product.mProductId];
            dispatch_async(dispatch_get_main_queue(), ^{
                // On the main thread, setup the UIKit objects:
                NSLog(@"%d", merge);
                /*
                for(ModifierItem *mod_product in modifier.activeModifiers)
                {
                    ...
                }
                numberOfModifiers++;
                */

                // Continue the loop:
                weak_block(array, completion);  //looks scary!
            });
        });
    };


    // Start the loop:

    block(marray, ^(id result){
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"result: %@", result);
            //[self setUpActiveModifierWithX:x andy:y Row:orderDetailRow andModifierList:modifierLists andProduct:product];
        });
    });
}