在foreach和dispatch之后做行动

时间:2014-04-25 08:23:31

标签: ios objective-c

我想在foreach和我的派遣之后做一个动作。在for循环中,当我遇到一种类型的枚举时,showAlert将得到YES。用于在所有任务和循环之后显示allert。

我已经尝试过了,但是当dispatch_sync仍在进行时,已经出现了这个问题。我该如何解决这个问题?

修改 问题概述:问题是UIAlertView已经在循环完成之前出现,所以我没有任何值集(For循环执行我的randomInt)并且我的AlertView接受此int。所以这就是为什么我要等到所有循环/ foreach都在方法中完成然后让UIAlertView出现,所以我有100%我需要的整数。

代码:

-(void)animateRolling{

    [[self firstLabelOutlet] setHidden:YES];

    long index;
    int randomIndex;
    __block BOOL showAllert = NO;

    randomIndex = arc4random() % 20;

    if (randomIndex == 8) {
        [self showAd];
    }

    for(detailDice* cell in [[self dobbelstenenCollection] visibleCells]){

        NSIndexPath *indexPath = [[self dobbelstenenCollection] indexPathForCell:cell];

        if ([arrayDobbel count] >= 3) {
            index = 2 * indexPath.section + indexPath.row;
        }else{
            index = 1 * indexPath.section + indexPath.row;
        }

        if ([cell isHidden]) {
            [cell setHidden:NO];
        }

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            for (int i = 0; i <= 10; i++) {

                dispatch_sync(dispatch_get_main_queue(), ^{
                    if ([[arrayDobbel objectAtIndex:index] diceSoort] == ENUMHoelangDobbel) {

                        randomInt = ((arc4random() % ([self maxduration] - 1 + 1 )) + 1.0);
                        [[cell detaildiceLabel] setText:[NSString stringWithFormat:@"Seconds \n %i", (int)randomInt]];

                        showAllert = YES;

                    }else if ([[arrayDobbel objectAtIndex:index] diceSoort] == ENUMOgen){

                        [[cell detailDiceImage] setImage:[UIImage imageNamed:[NSString stringWithFormat:@"%i.png", ( (arc4random() % (6-1+1)) + 1 )]]];

                    }else{
                        [[cell detaildiceLabel] setText: [[arrayDobbel objectAtIndex:index] returnRandomOptie]];
                    }

                });
                [NSThread sleepForTimeInterval:0.05];
            }
        });
    }

    if (showAllert) {
        [self showDurationAlert];
    }
}

亲切的问候!

2 个答案:

答案 0 :(得分:2)

使用dispatch_group_create创建群组。

使用dispatch_group_async代替dispatch_async

你的路径阻挡,应该在foreach之后执行并在dispatch_group_notify发送。

一切都很简单。

答案 1 :(得分:0)

我建议您通过animateRolling 异步方法重构代码,并调用showDurationAlert a&#34; continuation&#34;:

typedef void (^completion_t)(BOOL showAlert);

-(void)animateRollingWithCompletion:(completion_t)completion;

并按如下方式使用:

[self animateRollingWithCompletion:^(BOOL showAlert){
    if (showAlert) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self showDurationAlert];
        });
    }
}];

我还建议使用NSTimer或更好的调度计时器(dispatch_source_t)来实现方法animateRollingWithCompletion

您可以按如下方式创建和使用调度计时器:

// Create a timer:
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);

// Define the handler block:
dispatch_source_set_event_handler(timer, ^{
    ...
});

// Start the timer (here, as a one shot timer):
uint64_t leeway = 0; // allowed maximum delay
uint64_t interval = delay_in_secs * NSEC_PER_SEC;
dispatch_source_set_timer(
     timer, 
     dispatch_time(DISPATCH_TIME_NOW, interval), // time *when* to start
     DISPATCH_TIME_FOREVER,   // interval, DISPATCH_TIME_FOREVER for "one shot"
     leeway                   // maximum allowed delay
);
dispatch_resume(timer);

// Cancel a timer:
dispatch_source_cancel(timer);

为了启动一个定期计时器,其处理程序将在每个句点的 start 中调用,你可以写一下:

dispatch_source_set_timer(
     timer, 
     dispatch_time(DISPATCH_TIME_NOW, 0),
     interval, 
     leeway);
dispatch_resume(timer);

有了这些知识,我认为可以设计一个由周期性计时器驱动的处理程序块。该块从数组中检索参数并在主线程上执行核心方法(例如,设置单元格)。

当检索完所有参数并完成工作后,该块可以使用指定的时间间隔调用dispatch_after()(或测试&#34;在新时段开始时完成&#34;条件)最终调用在方法animateRollingWithCompletion中作为参数提供的完成块,并由调用站点(后者调出警报视图)定义。