Iphone 调度时间限制为10秒?

Iphone 调度时间限制为10秒?,iphone,objective-c,background,grand-central-dispatch,Iphone,Objective C,Background,Grand Central Dispatch,我正在开发一个在后台运行的应用程序。有时我需要告诉用户发生了什么事情,所以我会多次播放声音。为此,我制作了一个计时器,但问题是它不能超过总延迟时间的10秒,之后,就没有声音了(但应用程序仍在运行)。我已经在前台模式下检查了这个行为,它工作得非常好 这是我需要通知用户时的代码: AudioServicesPlaySystemSound(alarma); AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); numAl

我正在开发一个在后台运行的应用程序。有时我需要告诉用户发生了什么事情,所以我会多次播放声音。为此,我制作了一个计时器,但问题是它不能超过总延迟时间的10秒,之后,就没有声音了(但应用程序仍在运行)。我已经在前台模式下检查了这个行为,它工作得非常好

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



    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];
    });

“fibbtemps”是这样的


- (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

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

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

我怀疑链接异步块以定期播放声音有点过分了。也许以下简单的方法更容易理解和维护:

// 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;
        ...
    }
}
//要启动报警:
[自纤电磁脉冲:报警];
-(void)fiBGTemps:(int)发送方
{
开关(发送器){
...
案件报警:
调度异步(调度获取全局队列(调度队列优先级默认为0),^(无效){
整数计数=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;
        ...
    }
}
//要启动报警:
[自纤电磁脉冲:报警];
-(void)fiBGTemps:(int)发送方
{
开关(发送器){
...
案件报警:
调度异步(调度获取全局队列(调度队列优先级默认为0),^(无效){
整数计数=0;
同时(计数
问题已解决

事情就是这样。当应用程序在后台运行并且执行了一项任务时,此任务也在后台运行,但系统仅允许一定的时间(10秒)来保护电池安全。因此,它仅适用于特定的任务(本地化、下载等)

在我的情况下,我需要多一点时间,因此解决方案是将任务定义为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;
    });

在这里你可以看到苹果论坛上的讨论,他们比我解释得更好

我希望这有帮助

卡尼克

问题解决了

事情就是这样。当应用程序在后台运行并且执行了一项任务时,此任务也在后台运行,但系统仅允许一定的时间(10秒)来保护电池安全。因此,它仅适用于特定的任务(本地化、下载等)

在我的情况下,我需要多一点时间,因此解决方案是将任务定义为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;
    });

在这里你可以看到苹果论坛上的讨论,他们比我解释得更好

我希望这有帮助


Kanick

数字报警设置为什么?也许这就是限制循环数量的原因。此外,这里似乎有一系列两秒的延迟,而不是十秒的延迟。Hi@aLevelOfIndirection,NUM_ALARM是一个常数,我设置它来测试时间限制(#define NUM_ALARM 20)。这样我就可以看到声音发出了多少次。我测试的另一种方法是更改“延迟秒”值。如果我将此值设置为8(例如),它只播放2种声音。如果我将此值设置为12(大于10),它只播放一个声音。NUM_ALARM设置为什么?也许这就是限制循环数量的原因。此外,这里似乎有一系列两秒的延迟,而不是十秒的延迟。Hi@aLevelOfIndirection,NUM_ALARM是一个常数,我设置它来测试时间限制(#define NUM_ALARM 20)。这样我就可以看到声音发出了多少次。我测试的另一种方法是更改“延迟秒”值。如果我将此值设置为8(例如),它只播放2种声音。如果我将这个值设置为12(大于10),它只播放一个声音。是的,确实是这样。我已经将延迟设置为2秒,并且(对于测试)重复了5次以上(>10秒)。一旦达到10秒的时间,就没有更多的响应(这似乎是一个无限的时间)。所以我不能再这样做了。你能不能在(延迟,队列,^{[self-fiBGTemps:ALARM];})之后,在分派_之后,共享将传递给分派_的样本值;需要知道这些变量(延迟和队列)存储了什么。。。调度时间延迟=调度时间(现在调度时间,以秒为单位的延迟*每秒纳秒);调度队列=调度获取全局队列(调度队列优先级默认为0);您好,@Manikanthakur,这是在以下情况下传递给调度的内容:延迟秒=8(使用此值,它只播放一个声音),NSEC_PER_SEC是一个以时钟类型声明的常数。h(#定义NSEC_PER_SEC 1000000000ull),队列与我显示的相同