2013-04-30 63 views
1

我正在開發一個在後臺運行的應用程序。有時候我需要告訴用戶某些事情正在發生,所以我發出了一定數量的聲音。要做到這一點,我做了一個計時器,但問題是,它不能超過總延遲時間的10秒,之後,沒有更多的聲音(但應用程序仍在運行)。我已經在前景模式下檢查了這種行爲,並且它完美地工作。dispatch_after僅限於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]; 
    }); 

和 「fiBGTemps」 是這樣的,


- (void)fiBGTemps:(int)sender 
{ 
    switch (sender){ 
     case TEMP_SCAN: 
      (…) 
      break; 
     case ALARM: 
      if (numAlarm>0 && numAlarm&ltNUM_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

+0

什麼是NUM_ALARM設置爲?也許這就是限制循環次數的原因。此外,在這裏看來,你有兩秒的延遲序列,而不是十秒延遲。 – aLevelOfIndirection 2013-04-30 09:43:14

+0

Hi @aLevelOfIndirection,NUM_ALARM是一個常量,我設置了測試時間限制(#define NUM_ALARM 20)。通過這種方式,我可以看到聲音發出多少次。我測試的另一種方法是更改​​「delay_in_seconds」值。如果我將此值設置爲8(例如),它只播放2個聲音。如果我將此值設置爲12(超過10),它只播放一個聲音。 – Kanick 2013-04-30 09:59:38

回答

1

問題解決了。

這是發生了什麼事。當一個應用程序在後臺運行並且執行任務時,該任務也在後臺運行,但系統只允許一定的時間(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; 
    }); 

在這裏,你可以看到在蘋果論壇,在那裏,他們解釋這比我更好的討論。

AppleForums discussion

我希望這有助於。

Kanick

+0

你會在哪裏添加延遲? – 2017-07-18 10:14:30

0

您可以重新設置的延遲值嘗試後,超過的總延遲時間10秒,也可以是它起到聲音一定的時間之後。

+0

是的,的確,這就是我所做的。我已將延遲設置爲2秒,並且(對於測試),這會重複5次以上(> 10秒)。一旦達到了10秒的時間,就沒有更多的迴應(這似乎是無限的時間)。所以我不能再做。 – Kanick 2013-04-30 09:46:05

+0

你可以分享將傳遞給dispatch_after的樣本值: dispatch_after(delay,queue,[self fiBGTemps:ALARM]; }); 需要知道這些變量(延遲和隊列)存儲的內容... 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); – ManikantThakur 2013-04-30 10:34:30

+0

嗨,@ManikantThakur,這就是傳遞給dispatch_after:delay_in_seconds = 8(該值也只播放一個聲音),NSEC_PER_SEC是clock_types.h(#定義NSEC_PER_SEC 1000000000ull)宣佈恆定的,隊列是相同的我在上面的代碼中顯示,NUM_ALARM是15(這個值並不重要,重要的是NUM_ALARM * delay_in_seconds> 10s才能看到效果)。那是你要求的嗎? – Kanick 2013-04-30 11:05:49

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; 
     ... 
    } 
} 
+0

謝謝@aLevelOfIndirection。我剛剛嘗試過你的方法,並觀察到相同的結果。可能是問題不在代碼上(更清潔或者不在前臺運行良好)。可能有一些配置參數或類似的東西。 – Kanick 2013-04-30 10:52:44

+0

鬧鐘的聲音文件需要多長時間(以秒爲單位)? – aLevelOfIndirection 2013-04-30 11:05:17

+0

1秒(或更少)。 – Kanick 2013-04-30 11:07:58