2016-09-12 28 views
1

我有一些NSOperations在我的應用程序中定期啓動。即使應用程序置於後臺,它們也應該完成。爲此,我使用beginBackgroundTaskWithExpirationHandler方法。我可以使用beginBackgroundTaskWithName進行正常的應用程序處理嗎

我是否應該在每次啓動我的任務時使用beginBackgroundTaskWithExpirationHandler/endBackgroundTask:即使應用程序不會背景?或者我只是在我檢測到UIApplicationDidEnterBackgroundNotification時纔將這個電話稱爲開始/結束方法?

方法1:使用後臺任務每次

/** 
* This method is called regularly from a NSTimer 
*/ 
- (void)processData 
{ 
    __block UIBackgroundTaskIdentifier operationBackgroundId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ 
     [[UIApplication sharedApplication] endBackgroundTask:operationBackgroundId]; 
     operationBackgroundId = UIBackgroundTaskInvalid; 
    }]; 

    NSOperation *operation = ... 
    [self.queue addOperation:operation]; 

    operation.completionBlock = ^{ 
     [[UIApplication sharedApplication] endBackgroundTask:operationBackgroundId]; 
     operationBackgroundId = UIBackgroundTaskInvalid; 
    }; 
} 

選項2:使用後臺任務只有當應用程序即將赴背景

/** 
* This method is called regularly from a NSTimer 
*/ 
- (void)processData 
{ 

    NSOperation *operation = ... 
    [self.queue addOperation:operation]; 

} 


- (void)applicationDidEnterBackground:(NSNotification *)notification 
{ 
    __block UIBackgroundTaskIdentifier operationBackgroundId = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"EnterBackgroundFlushTask" expirationHandler:^{ 
     [[UIApplication sharedApplication] endBackgroundTask:operationBackgroundId]; 
     operationBackgroundId = UIBackgroundTaskInvalid; 
    }]; 

    // wait for all operations to complete and then 


    // let UIApplication know that we are done 
    [[UIApplication sharedApplication] endBackgroundTask:operationBackgroundId]; 
} 

回答

5

回答我的問題。從Apple Docs

你並不需要等到您的應用程序移動到後臺候 後臺任務。更有用的設計是調用 beginBackgroundTaskWithName:expirationHandler:或 beginBackgroundTaskWithExpirationHandler:開始 任務之前的方法,並在完成後立即調用endBackgroundTask:方法。當你的應用在 前臺執行時,你甚至可以按照這種模式。

其他Apple API reference

你應該叫有時​​這種方法,其中未完成留下一個任務可能不利於你的應用程序的用戶體驗。

您可以在應用程序執行的任何時候調用此方法。

-1

1選項是正確的選項。這裏是來自Apple文檔的代碼供您參考。

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ 
    bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{ 
     // Clean up any unfinished task business by marking where you 
     // stopped or ending the task outright. 
     [application endBackgroundTask:bgTask]; 
     bgTask = UIBackgroundTaskInvalid; 
    }]; 

    // Start the long-running task and return immediately. 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     // Do the work associated with the task, preferably in chunks. 

     [self processData]; 
     [application endBackgroundTask:bgTask]; 
     bgTask = UIBackgroundTaskInvalid; 
    }); 
} 

Apple developer Guide

+0

但是蘋果文檔說:「你應該調用這個方法,有時候任務未完成可能會對你的應用程序的用戶體驗造成不利影響,你可以在你的應用程序執行的任何時候調用這個方法」https:// developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/index.html#//apple_ref/occ/instm/UIApplication/beginBackgroundTaskWithExpirationHandler – Jan

+0

選項2的問題在於我必須跟蹤已發生的事情開始,什麼不是。示例代碼很簡單,但真正的代碼更復雜 – Jan

+0

實際上,在您發佈的同一鏈接中,Apple會說:「您不需要等到應用程序移動到背景以指定後臺任務。更有用的設計是在開始任務之前調用beginBackgroundTaskWithName:expirationHandler:或beginBackgroundTaskWithExpirationHandler:方法,並在完成後立即調用endBackgroundTask:方法,甚至可以在前臺執行應用程序時遵循此模式。「 – Jan

相關問題