区分 iPhone 应用程序崩溃和被杀死

发布于 2024-11-28 18:55:47 字数 112 浏览 4 评论 0原文

你好,我计划开发一个简单的 iPhone 游戏。我希望能够区分真正的崩溃和用户杀死应用程序(通过双击主屏幕并长按它来杀死它)。

有人可以解释一下当用户通过多任务栏杀死应用程序时到底会发生什么吗?

Hello I am planning to develop a simple iPhone game. I would like to be able to distinguish between a genuine crash, and the user killing the app ( by double tapping home screen and long-clicking it to kill it) .

Can someone please shed some light on what exactly happens when the user kill the app through the multitasking bar.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

稀香 2024-12-05 18:55:47

如果您的应用程序处于后台并在用户终止它时暂停,它将不会收到任何通知。这占大多数情况。

如果您的应用当前正在后台运行(只有非常特定类别的应用可以执行此操作),那么它会收到 applicationWillTerminate

事实上,苹果非常清楚,你应该在进入后台之前保存任何相关数据。看看 (“响应应用程序终止”一章):

即使您使用 iOS SDK 4 及更高版本开发应用程序,您仍然必须做好应用程序在没有任何通知的情况下被终止的准备。 用户可以使用多任务 UI 显式终止应用程序。此外,如果内存变得有限,系统可能会从内存中删除应用程序以腾出更多空间。 如果您的应用程序当前已暂停,系统会终止您的应用程序并将其从内存中删除,恕不另行通知。但是,如果您的应用程序当前正在后台状态运行(换句话说,未挂起),系统将调用应用程序委托的 applicationWillTerminate: 方法。您的应用程序无法从此方法请求额外的后台执行时间。

编辑:

关于“说抱歉”的事情......

你当然可以在下一次发布时做到这一点。只需将一个密钥存储在 NSUserDefaults 中,并在应用程序进入后台时将其删除(我希望这一切听起来对您来说很熟悉,否则请查看 UIApplicationDelegate 协议)。

当应用程序启动时,您检查密钥;如果存在,则用户没有关闭该应用程序;如果应用程序不存在,那么用户至少将应用程序移动到后台并且没有遇到任何突然终止...

If your app is in the background and suspended when the user kills it, it will receive no notification. This accounts for the majority of cases.

If your app is currently running in the background (there are only very specific categories of apps that can do that), then it receives applicationWillTerminate.

Indeed, Apple is very clear as to the fact that you should save any relevant data before entering the background. Have a look at this (chapter "Responding to Application Termination"):

Even if you develop your application using iOS SDK 4 and later, you must still be prepared for your application to be killed without any notification. The user can kill applications explicitly using the multitasking UI. In addition, if memory becomes constrained, the system might remove applications from memory to make more room. If your application is currently suspended, the system kills your application and removes it from memory without any notice. However, if your application is currently running in the background state (in other words, not suspended), the system calls the applicationWillTerminate: method of your application delegate. Your application cannot request additional background execution time from this method.

EDIT:

about the "saying sorry" thing...

you can certainly do that on the next launch. simply store a key in NSUserDefaults and remove it when the app enters the background (I hope all this sounds familiar to you, otherwise look into the UIApplicationDelegate protocol).

when the app starts up, you check the key; if it is there, then the app was not closed by the user; if the app is not there, then the user at least moved the app to the background and did not experience any sudden termination...

素食主义者 2024-12-05 18:55:47

对于 iOS6 及更高版本有一种方法可以做到这一点。 状态恢复的副作用是它会删除恢复期间发生崩溃或用户手动终止应用程序时的状态。您可以利用这一点来检测用户手动杀死该应用程序。

来自

请注意,当用户强制退出应用程序时,系统会自动删除应用程序的保留状态。当应用程序被终止时删除保留的状态信息是一种安全预防措施。 (作为类似的安全预防措施,如果应用程序在启动时崩溃,系统也会删除保留的状态。)如果您想测试应用程序恢复其状态的能力,则不应在调试期间使用多任务栏来终止应用程序。相反,使用 Xcode 终止应用程序或通过安装临时命令或手势来按需调用退出以编程方式终止应用程序。

以下代码假设您已经有一个名为 _didCrashInLastSession 的用于崩溃检测的 BOOL。获取此值的方法有多种,例如这个第三方库。在您的代码中调用方法 [self getLaunchType] 来查看您正在处理的启动类型并采取相应的操作。将以下内容放入您的 AppDelegate.m 中:

typedef NS_ENUM(NSInteger, LaunchType) {
    LaunchTypeUnknown,
    LaunchTypeNewInstall,
    LaunchTypeNormalLaunch,
    LaunchTypeCrashedLastSession,
    LaunchTypeUserManualQuit,
};

static BOOL hadStateToRestore = NO;
static NSString * const kAppHasEverRunKey = @"appHasEverRun";

- (BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder
{
    // Called when going into the background
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kAppHasEverRunKey];
    [[NSUserDefaults standardUserDefaults] synchronize];

    return YES;
}

- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder
{
    // Called on start up
    hadStateToRestore = YES;
    return YES;
}

- (LaunchType)getLaunchType
{
    if (_didCrashInLastSession) {
        return LaunchTypeCrashedLastSession;
    }

    if (![[NSUserDefaults standardUserDefaults] boolForKey:kAppHasEverRunKey]) {
        return LaunchTypeNewInstall;
    }

    if (!hadStateToRestore) {
        return LaunchTypeUserManualQuit;
    }

    return LaunchTypeNormalLaunch;
}

更新:至少有一个第 3 方 SDK 打破了这一技术:Urban Airship。

For iOS6 and later there is a way to do this. A side effect of State Restoration is that it will delete the state when there is either a crash during restore or a user manually kills the app. You can use this to your advantage to detect a user manually killing the app.

From the documentation:

Be aware that the system automatically deletes an app’s preserved state when the user force quits the app. Deleting the preserved state information when the app is killed is a safety precaution. (The system also deletes preserved state if the app crashes at launch time as a similar safety precaution.) If you want to test your app’s ability to restore its state, you should not use the multitasking bar to kill the app during debugging. Instead, use Xcode to kill the app or kill the app programmatically by installing a temporary command or gesture to call exit on demand.

The following code assumes that you already have a BOOL for crash detection called _didCrashInLastSession. There are different approaches for getting this value such as this 3rd party library. In your code call the method [self getLaunchType] to see which type of launch you are dealing with and act on that accordingly. Put the following in your AppDelegate.m:

typedef NS_ENUM(NSInteger, LaunchType) {
    LaunchTypeUnknown,
    LaunchTypeNewInstall,
    LaunchTypeNormalLaunch,
    LaunchTypeCrashedLastSession,
    LaunchTypeUserManualQuit,
};

static BOOL hadStateToRestore = NO;
static NSString * const kAppHasEverRunKey = @"appHasEverRun";

- (BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder
{
    // Called when going into the background
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kAppHasEverRunKey];
    [[NSUserDefaults standardUserDefaults] synchronize];

    return YES;
}

- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder
{
    // Called on start up
    hadStateToRestore = YES;
    return YES;
}

- (LaunchType)getLaunchType
{
    if (_didCrashInLastSession) {
        return LaunchTypeCrashedLastSession;
    }

    if (![[NSUserDefaults standardUserDefaults] boolForKey:kAppHasEverRunKey]) {
        return LaunchTypeNewInstall;
    }

    if (!hadStateToRestore) {
        return LaunchTypeUserManualQuit;
    }

    return LaunchTypeNormalLaunch;
}

Update: At least one 3rd party SDK breaks this technique: Urban Airship.

会发光的星星闪亮亮i 2024-12-05 18:55:47

您也可以通过您的设备来完成此操作。
将您的设备连接到您的机器。
运行 xcode 并转到管理器。
在那里选择您的设备和设备日志。
在那里您还可以查看应用程序或游戏的崩溃日志。

You can do it through your device also.
Connect your device to your machine.
Run xcode and go to organizer.
There select your device and device logs.
There you can also see crash logs of your app or game.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文