写之前先声明一下:OC是最好的语言!🤔
iPhone向来是如此的流畅,就算是我手里如此垃圾的iPhone5S,1G内存也能听着歌,开着QQ,聊着微信,还可以打一把王者农药,然后还可以上来刷一刷简书的博客,好了进入正题:
那么iPhone流畅的原因是什么呢?我想很大一部分原因是iPhone严格的后台运行保护机制,绝大部分程序在后台都撑不过10分钟,所以实际上只运行了一个程序,那肯定不卡了。
不过我们目前的主题不是这个,作为开发者的我绝对忍受不了它3秒钟都不给我的态度😡😡,只要一退到后台,所有线程立马被挂起!!太傲娇了,既然有10分钟,那么就一定要争取到!上代码:
向iOS申请,在后台完成一个Long-Running Task任务
1.项目的AppDelegate.h文件中
@interface AppDelegate ()
@property (nonatomic, unsafe_unretained) UIBackgroundTaskIdentifier backgroundTaskIdentifier;
@property (nonatomic, strong) NSTimer *myTimer;
@end
2、在 AppDelegate 的 applicationDidEnterBackground 方法中调用我们需要后台执行的方法:
self.backgroundTaskIdentifier =[application beginBackgroundTaskWithExpirationHandler:^(void) {
//当后台时间要结束的时候就会调用这个Block
//此时我们需要结束后台任务,
[self endBackgroundTask];
}];
// 模拟一个Long-Running Task
self.myTimer =[NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:@selector(timerMethod:)
userInfo:nil
repeats:YES];
注意这里不能企图开任何的线程来调用方法,因为所有的线程都会被挂起
3、实现后台任务结束的方法
后台任务一结束,我们首先需要释放定时器,然后告诉iOS我们的任务已经完成了,下面是实现部分:
- (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);
}
}
到这里后台任务就算执行成功了,不会一退到后台就会被挂起,附上demo地址:【下载demo】