我需要在後臺以及前臺執行長時間運行的任務。這會更新核心數據。所以爲了保持UI響應,我創建了另一個線程,我使用了不同的managedObjectContext(MOC)。所以一個計時器在後臺和前臺設置,並且在狀態改變時被適當地禁用。在任務開始之前和任務完成後,當我按Home按鈕時,它會正確調用兩個委託方法,但在任務處於活動狀態時,當我按Home按鈕屏幕更改並且UI掛起(變爲空白),但兩個委託方法不是正確調用,應用程序不會終止。我無法找到發生這種情況的原因。如果有人能幫忙,這將會有所幫助。在iOS模擬器中按下home按鈕時,不會調用applicationDidEnterBackground和applicationWillEnterForeground方法
我會附上所需的代碼與此:
-(void) startTimerThread
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// Add code here to do background processing
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:[(AppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator]];
self.managedObjectContext = context;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(mergeChanges:)
name:NSManagedObjectContextDidSaveNotification
object:context];
NSLog(@"managedObjContext : %@\n",self.managedObjectContext);
[self getDataFromFile];
dispatch_async(dispatch_get_main_queue(), ^{
// Add code here to update the UI/send notifications based on the
// results of the background processing
[[NSNotificationCenter defaultCenter] postNotificationName:@"ReloadAppDelegateTable" object:nil];
[context release];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSManagedObjectContextDidSaveNotification
object:context];
});
});
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(@"Background\n");
[self.notificationTimer invalidate];
self.notificationTimer = nil;
UIApplication *app = [UIApplication sharedApplication];
self.bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
//start location update timer and background timer
self.timer = [NSTimer scheduledTimerWithTimeInterval:180 target:self
selector:@selector(startLocationServices) userInfo:nil repeats:YES];
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
self.logDownloader.managedObjectContext = self.managedObjectContext;
NSLog(@"managedObjContext : %@\n",self.logDownloader.managedObjectContext);
self.backgroundTimer = [NSTimer scheduledTimerWithTimeInterval:90 target:self.logDownloader selector:@selector(getDataFromFile) userInfo:nil repeats:YES];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSLog(@"Foreground\n");
//invalidate background timer and location update timer
[self.timer invalidate];
[self.backgroundTimer invalidate];
self.timer = nil;
self.notificationTimer = nil;
self.logDownloader.managedObjectContext = self.managedObjectContext;
NSLog(@"managedObjContext : %@\n",self.logDownloader.managedObjectContext);
[[NSNotificationCenter defaultCenter] postNotificationName:@"ReloadAppDelegateTable" object:nil];
self.notificationTimer = [NSTimer scheduledTimerWithTimeInterval:180 target:self.logDownloader selector:@selector(startTimerThread) userInfo:nil repeats:YES];
}
非常感謝。我現在可以理解。這非常有幫助。其實我只想在計時器後臺撥打電話。並且此應用程序正在使用位置服務,因此它將「應用程序不在後臺運行」中的info.plist設置爲「YES」。有什麼方法可以知道它是否進入背景? – aparna 2013-04-13 17:49:01
把一些'NSLogs'運行在'NSTimers'上,但是你會知道它是否被髮送到後臺,因爲一旦你回到應用程序,運行的應用程序實例將繼續運行。 – Popeye 2013-04-13 17:52:44
只需確保將「應用程序不在後臺運行」設置爲NO,並且它將在後臺運行。 – Popeye 2013-04-13 17:54:24