一,工程圖。 二,代碼。 AppDelegate.h AppDelegate.m RootViewController.h RootViewController.m
一,工程圖。
二,代碼。
AppDelegate.h
AppDelegate.m
RootViewController.h
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic, unsafe_unretained) UIBackgroundTaskIdentifier backgroundTaskIdentifier;
@property (nonatomic, strong) NSTimer *myTimer;
@end
RootViewController.m
#import "AppDelegate.h"
#import "RootViewController.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
RootViewController *rootVC=[[RootViewController alloc]init];
UINavigationController *nav=[[UINavigationController alloc]initWithRootViewController:rootVC];
self.window.rootViewController=nav;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// 使用這個方法來釋放公共的資源、存儲用戶數據、停止我們定義的定時器(timers)、並且存儲在程式終止前的相關信息。
// 如果,我們的應用程式提供了後臺執行的方法,那麼,在程式退出時,這個方法將代替applicationWillTerminate方法的執行。
// 標記一個長時間運行的後臺任務將開始
// 通過調試,發現,iOS給了我們額外的10分鐘(600s)來執行這個任務。
self.backgroundTaskIdentifier =[application beginBackgroundTaskWithExpirationHandler:^(void) {
// 當應用程式留給後臺的時間快要到結束時(應用程式留給後臺執行的時間是有限的), 這個Block塊將被執行
// 我們需要在次Block塊中執行一些清理工作。
// 如果清理工作失敗了,那麼將導致程式掛掉
// 清理工作需要在主線程中用同步的方式來進行
[self endBackgroundTask];
}];
// 模擬一個Long-Running Task
self.myTimer =[NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:@selector(timerMethod:) userInfo:nil
repeats:YES];
}
- (void) endBackgroundTask{
dispatch_queue_t mainQueue = dispatch_get_main_queue();
AppDelegate *weakSelf = self;
dispatch_async(mainQueue, ^(void) {
AppDelegate *strongSelf = weakSelf;
if (strongSelf != nil){
[strongSelf.myTimer invalidate];// 停止定時器
// 每個對 beginBackgroundTaskWithExpirationHandler:方法的調用,必須要相應的調用 endBackgroundTask:方法。這樣,來告訴應用程式你已經執行完成了。
// 也就是說,我們向 iOS 要更多時間來完成一個任務,那麼我們必須告訴 iOS 你什麼時候能完成那個任務。
// 也就是要告訴應用程式:“好借好還”嘛。
// 標記指定的後臺任務完成
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskIdentifier];
// 銷毀後臺任務標識符
strongSelf.backgroundTaskIdentifier = UIBackgroundTaskInvalid;
}
});
}
// 模擬的一個 Long-Running Task 方法
- (void) timerMethod:(NSTimer *)paramSender{
// backgroundTimeRemaining 屬性包含了程式留給的我們的時間
NSTimeInterval backgroundTimeRemaining =[[UIApplication sharedApplication] backgroundTimeRemaining];
if (backgroundTimeRemaining == DBL_MAX){
//前臺列印
NSLog(@"Background Time Remaining = Undetermined");
} else {
//後臺列印
NSLog(@"Background Time Remaining = %.02f Seconds", backgroundTimeRemaining);
}
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
//添加此段代碼,則在前臺就不運行了。否則會前後臺一起運行。除第一次啟動的時候,是前臺不運行,退出後臺時候運行。
if (self.backgroundTaskIdentifier != UIBackgroundTaskInvalid){
[self endBackgroundTask];
}
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end