dispatch_after限制为10秒?

时间:2013-04-30 08:58:40

标签: iphone objective-c background grand-central-dispatch

我正在开发一个在后台运行的应用。有时我需要告诉用户发生了什么事情,所以我播放了一定次数的声音。为了做到这一点,我做了一个计时器,但问题是它不能超过总延迟时间的10s,之后,没有更多的声音(但应用程序仍在运行)。我已经在前台模式中检查了这种行为并且它运行良好。

当我需要通知用户时,这是我的代码:



    AudioServicesPlaySystemSound(alarma);
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    numAlarm = 1;  
    NSTimeInterval delay_in_seconds = 2.0;
    dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW,delay_in_seconds*NSEC_PER_SEC);
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
    dispatch_after(delay,queue,^{
        [self fiBGTemps:ALARM];
    });

和“fiBGTemps”是这样的,


- (void)fiBGTemps:(int)sender
{
    switch (sender){
        case TEMP_SCAN:
            (…)
            break;
        case ALARM:
            if (numAlarm>0 && numAlarm<NUM_ALARM)
            {
                AudioServicesPlaySystemSound(alarma);
                AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
                NSTimeInterval delay_in_seconds = 2;
                dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW,delay_in_seconds*NSEC_PER_SEC);
                dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
                dispatch_after(delay,queue,^{
                    [self fiBGTemps:ALARM];
                });
                numAlarm++;
            }
            break;
    }
}

这种行为是正常的吗?我错过了什么吗?

由于

Kanick

3 个答案:

答案 0 :(得分:1)

问题解决了。

这就是发生的事情。当应用程序在后台运行并执行任务时,此任务也在后台运行,但系统只允许一定的时间(10s围裙。)以安全电池。因此它仅适用于特定任务(本地化,下载等)。

我的情况我需要更多时间,因此解决方案是将任务定义为UIBackgroundTask,这将是在完成后通知系统并因此可以终止的任务。

这是它被称为任务的代码:



    UIApplication *application = [UIApplication sharedApplication];
    __block UIBackgroundTaskIdentifier background_task;
    background_task = [application beginBackgroundTaskWithExpirationHandler: ^{
        [application endBackgroundTask: background_task];
        background_task = UIBackgroundTaskInvalid;
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self fiBGTemps:@(ALARM)];
        [application endBackgroundTask: background_task];
        background_task = UIBackgroundTaskInvalid;
    });

在这里你可以看到关于Apple论坛的讨论,他们在那里解释这个比我更好。

AppleForums discussion

我希望这会有所帮助。

Kanick

答案 1 :(得分:0)

您可以尝试在延迟时间超过总延迟时间的10秒后重新设置延迟值,也可以在延迟值播放声音一段时间后重新设置。

答案 2 :(得分:0)

我怀疑链接异步阻塞以定期播放声音有点过分。也许沿着以下方面更简单的东西将更容易理解和维护:

// To initiate the alarm:
[self fiBGTemps: ALARM];

- (void)fiBGTemps:(int)sender
{
    switch (sender) {
       ...
       case ALARM:
           dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
                int count = 0;
                while (count < NUM_ALARM /* AND not interrupted by user? */) {
                    sleep(2);
                    AudioServicesPlaySystemSound(alarma);
                    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
                    count++;
                }
            });
            break;
        ...
    }
}