在 iOS 模拟器中按下主页按钮时不会调用 applicationDidEnterBackground 和 applic

applicationDidEnterBackground and applicationWillEnterForeground method are not called when pressed home button in iOS simulator(在 iOS 模拟器中按下主页按钮时不会调用 applicationDidEnterBackground 和 applicationWillEnterForeground 方法) - I
本文介绍了在 iOS 模拟器中按下主页按钮时不会调用 applicationDidEnterBackground 和 applicationWillEnterForeground 方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我需要在后台和前台完成一项长时间运行的任务.这会更新核心数据.因此,为了保持 UI 响应,我创建了另一个线程,在其中使用不同的 managedObjectContext(MOC).因此,在后台和前台都设置了一个计时器,并在状态更改时适当地停用.在任务开始之前和任务完成之后,当我按下主页按钮时,它会正确调用两个委托方法,但是当我按下主页按钮屏幕更改和 UI 挂起(变为空白)时,任务处于活动状态,但两个委托方法不是正确调用并且应用程序不会终止.我找不到发生这种情况的原因.如果有人可以提供帮助会很有帮助.

I need a long running task to be done in background as well as in foreground. This updates the core data. So to maintain UI responsive I created an another thread where I use different managedObjectContext(MOC). So a timer is set in background as well as in foreground and is inactivated appropriately when state changes. Before the task is starting and after the task is completed when I press home button it calls the two delegate methods properly but during the task is active when I press home button screen changes and UI hangs (becomes blank) but the two delegate methods are not called properly and the app is not terminated. I could not find the reason why this happens so. It would be helpful if someone can help.

我将附上所需的代码:

-(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 : %@
",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
");
    [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 : %@
",self.logDownloader.managedObjectContext);
    self.backgroundTimer = [NSTimer scheduledTimerWithTimeInterval:90 target:self.logDownloader selector:@selector(getDataFromFile) userInfo:nil repeats:YES];
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    NSLog(@"Foreground
");
    //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 : %@
",self.logDownloader.managedObjectContext);
    [[NSNotificationCenter defaultCenter] postNotificationName:@"ReloadAppDelegateTable" object:nil];

    self.notificationTimer = [NSTimer scheduledTimerWithTimeInterval:180 target:self.logDownloader selector:@selector(startTimerThread) userInfo:nil repeats:YES];
}

推荐答案

原因applicationDidEnterBackground:applicationDidEnterForeground: 永远不会被调用,因为这些方法与 应用程序不在后台运行这个选项可以在你的***-info.plist中找到.如果此选项设置为 YES ,那么您的应用程序将永远不会调用这些方法,因为当您使用已将选项设置为 YES 实例的应用程序按下主页按钮时,这些方法正在运行的应用程序将被终止,因此每次按下主页按钮然后选择应用程序图标时,都会创建一个新实例,因此它正在使用 applicationWillTerminate:.

The reason why applicationDidEnterBackground: and applicationDidEnterForeground: are never called is because these methods are used in joint with Application does not run in background this option can be found in your ***-info.plist. If this option is set to YES than your app will never call these methods, because these when you press the home button with an app that has set the option to YES the instance of the app that is running will get terminated so everytime you press the home button and then select the app icon a new instance is being created so it is using applicationWillTerminate:.

Kirti mali 所说的方法也将是不正确的方法来使用你想要的,原因是 applicationDidBecomeActive:applicationWillResignActive: 用于接听电话等情况.正在运行的实例不会被终止,也不会被发送到后台.该实例会暂停,直到用户完成该调用,然后它将再次变为活动状态.

The methods that Kirti mali has said would also be the incorrect methods to use for want you are after, the reason being is that applicationDidBecomeActive: and applicationWillResignActive: are used when something like when you answer a phone call. The instance running is not terminated neither is it sent to the background. The instance is paused until the user has finished on that call when it will become active again.

因此,如果您希望应用程序在后台运行,解决方案是更改选项应用程序不在后台运行".在 ***-info.plist 中为 NO 只是 applicationDidBecomeActive:applicationWillResignActive: 是这些方法的错误使用方式.

So the solution to this would be if you want the app to run in background would be to change the option "Application does not run in background" in the ***-info.plist to be NO just applicationDidBecomeActive: and applicationWillResignActive: is the wrong way for these methods to be used.

请参阅 上的苹果文档UIApplicationDelegate 以更好地理解这些方法.

Please see the apple documentation on UIApplicationDelegate to get a better understanding of these methods.

这篇关于在 iOS 模拟器中按下主页按钮时不会调用 applicationDidEnterBackground 和 applicationWillEnterForeground 方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

Facebook Requests Dialog: Frictionless Requests in native iOS app possible?(Facebook 请求对话框:本机 iOS 应用程序中的无摩擦请求可能吗?)
Difference between iPhone Simulator and Android Emulator(iPhone模拟器和Android模拟器之间的区别)
iOS 6 (iPhone/iPad) Image Upload quot;Request Body Stream Exhaustedquot; with NTLM/Windows Authentication(iOS 6 (iPhone/iPad) 图片上传“请求正文流用尽使用 NTLM/Windows 身份验证)
Can#39;t change target membership visibility in Xcode 4.5(无法更改 Xcode 4.5 中的目标成员身份可见性)
UITableView: Handle cell selection in a mixed cell table view static and dynamic cells(UITableView:在混合单元格表视图静态和动态单元格中处理单元格选择)
How to remove Address Bar in Safari in iOS?(如何在 iOS 中删除 Safari 中的地址栏?)