【发布时间】:2015-02-06 13:32:02
【问题描述】:
我的应用通过 BLE 从外围设备下载大量数据。如果我锁定屏幕,我的应用程序将移至后台并启动后台任务。下载完成正常,但如果处理(由于数据量很大,需要相当长的时间)开始应用程序崩溃,因为它无法连接到数据库。
我想在那时停止执行并等待应用程序再次激活,但不知何故我无法实现这一点。我想我需要某种信号量来等待应用激活。
到目前为止,这是我的代码:
- (void)viewDidLoad
{
//Some other code
//initialize flag
isInBackgroud = NO;
// check if app is in the background
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
// check if app is in the foreground
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterForeground) name:UIApplicationDidBecomeActiveNotification object:nil];
}
- (void)appDidEnterBackground {
NSLog(@"appDidEnterBackground");
isInBackground = YES;
UIApplication *app = [UIApplication sharedApplication];
NSLog(@"remaining Time: %f", [app backgroundTimeRemaining]);
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"expirationHandler");
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
}
- (void)appDidEnterForeground {
NSLog(@"appDidEnterForeground");
isInBackground = NO;
if (bgTask != UIBackgroundTaskInvalid) {
UIApplication *app = [UIApplication sharedApplication];
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
}
//BLE connection and reading data via notification
//when finished [self processData] is called.
- (void)processData {
if (isInBackground) {
//set reminder
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate date];
localNotification.alertBody = [NSString stringWithFormat:@"Data was downloaded, return to the application to proceed processing your data."];
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
UIApplication *app = [UIApplication sharedApplication];
//end background task
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
//wait for application to become active again
while (isInBackground) {
NSLog(@"isInBackground");
NSLog(@"remaining Time: %f", [app backgroundTimeRemaining]);
sleep(1);
}
//process data
}
所以我注意到,如果我调用[app endBackgroundTask:bgTask];,应用程序会继续运行,但当我想连接到我的数据库时会崩溃。这就是我添加while(isInBackground) 循环的原因。我知道这不是一个好习惯,因为它在做笔记时会主动浪费 CPU 时间。那时我应该使用信号量,但我不知道该怎么做。
因为我在那个循环中积极地等待,所以永远不会调用 appDidEnterForegronund 并且循环永远运行。
【问题讨论】:
标签: ios objective-c cocoa-touch semaphore