当用户退出应用程序时保存核心数据?

4
我试图在用户按下主屏幕按钮时保存Core Data。我想从-applicationDidEnterBackground:中执行此操作,但是它没有被调用。这可能是因为不能从这里保存Core Data,或者仅仅是因为操作完成的时间不够。然而,从-applicationWillResignActive:中可以正常工作。我只是好奇哪个委托方法是最好的来执行此操作,以及为什么-applicationDidEnterBackground:没有起作用。(从输出结果可以看出,两种方法都被调用了。如果我从-applicationWillResignActive:中删除保存操作,则根本不会发生任何事情,因此不是一种阻塞另一种的情况。)
// CALLS SAVE
- (void)applicationWillResignActive:(UIApplication *)application {
    [[self model] saveCoreData:@"SAVE FROM: applicationWillResignActive"];
    NSLog(@"APPDEL: %s", __PRETTY_FUNCTION__);
}

// DOES NOT CALL SAVE
- (void)applicationDidEnterBackground:(UIApplication *)application {
    [[self model] saveCoreData:@"SAVE FROM: applicationDidEnterBackground"];
    NSLog(@"APPDEL: %s", __PRETTY_FUNCTION__);
}

.

// CONSOLE OUTPUT
2013-03-21 cvb[6724:907] APPDEL: -[AppDelegate applicationWillResignActive:]
2013-03-21 cvb[6724:907] APPDEL: -[AppDelegate applicationDidEnterBackground:]
2013-03-21 cvb[6724:907]  
2013-03-21 cvb[6724:907] SAVE: SAVE FROM: applicationWillResignActive
2013-03-21 cvb[6724:907] SAVE: Saving successful ...

编辑:

最终我做了以下修改:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    __block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];
    [[self model] saveCoreData:@"[ENTERING BACKGROUND]"];
}

谢谢 Guo,你比我先完成了。 - fuzzygoat
applicationDidEnterBackground中的model的值是多少?我猜它不是nil吧? - occulus
你的 saveCoreData 方法是异步工作还是会在保存完成前阻塞?保存需要多长时间? - occulus
能否节省超过5秒的时间?如果可以,尝试在不同的线程中使用beginBackgroundTaskWithExpirationHandler..从iOS请求后台执行时间。 - nzs
我也会尝试优化Core Data以提高性能。请查看此Core Data优化章节,并使用Instruments工具查看Core Data的活动情况:https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CoreData/Articles/cdPerformance.html - nzs
我不认为在applicationDidEnterBackground中model为空,我会检查一下。在这个方法之前它不是空的,因为我在这之前保存了几次。 - fuzzygoat
1个回答

2

请查看UIApplicationDelegate协议参考

基本上,这是关于applicationDidEnterBackground:可能会引起您兴趣的部分:

在此方法退出之前,您应该执行与调整用户界面相关的任何任务,但其他任务(例如保存状态)应根据需要移动到并发调度队列或辅助线程。因为您开始在applicationDidEnterBackground:中启动的任何后台任务可能要等到该方法退出后才能运行,所以您应该在开始这些任务之前请求额外的后台执行时间。换句话说,首先调用beginBackgroundTaskWithExpirationHandler:,然后在调度队列或辅助线程上运行任务。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接