287

iPhone アプリをプログラミングしていますが、特定のユーザー アクションのために強制的に終了させる必要があります。アプリが割り当てたメモリをクリーンアップした後、アプリケーションを終了するために呼び出す適切なメソッドは何ですか?

4

24 に答える 24

276

iPhone では、アプリを終了するという概念はありません。アプリを終了させる唯一のアクションは、電話のホーム ボタンに触れることであり、これは開発者がアクセスできるものではありません。

Apple によると、アプリは勝手に終了するべきではありません。ユーザーはホーム ボタンを押していないため、ホーム画面に戻ると、アプリがクラッシュしたような印象をユーザーに与えます。これは紛らわしい非標準の動作であり、回避する必要があります。

于 2008-12-10T14:54:06.467 に答える
221

試しましたexit(0)か?

あるいは、[[NSThread mainThread] exit]私は試していませんが、より適切な解決策のようです。

于 2008-12-10T05:49:12.620 に答える
41

ここで Q&A を確認してください: https://developer.apple.com/library/content/qa/qa1561/_index.html

Q: プログラムで iOS アプリケーションを終了するにはどうすればよいですか?

iOS アプリケーションを正常に終了するための API は提供されていません。

iOS では、ユーザーはホーム ボタンを押してアプリケーションを閉じます。アプリケーションが意図した機能を提供できない状況にある場合、推奨されるアプローチは、問題の性質と、ユーザーが実行できる可能性のあるアクション (WiFi をオンにする、位置情報サービスを有効にするなど) を示すアラートをユーザーに表示することです。ユーザーが自分の判断でアプリケーションを終了できるようにします。

警告:関数を呼び出さないでくださいexit。アプリケーションの呼び出しexitは、適切な終了を実行してホーム画面にアニメーションで戻るのではなく、クラッシュしたようにユーザーに表示されます。

-applicationWillTerminate:さらに、exit を呼び出すと同様のUIApplicationDelegateメソッドが呼び出されないため、データが保存されない場合があります。

開発中またはテスト中にアプリケーションを終了する必要がある場合は、abort関数またはassertマクロを使用することをお勧めします

于 2010-06-05T14:31:59.460 に答える
39

プログラムをやめる方法ではなく、強制的にやめさせる方法です。

UIAlertView *anAlert = [[UIAlertView alloc] initWithTitle:@"Hit Home Button to Exit" message:@"Tell em why they're quiting" delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
[anAlert show];
于 2009-08-04T00:59:29.917 に答える
38

info.plistに移動し、「アプリケーションがバックグラウンドで実行されない」キーを確認します。今回、ユーザーがホームボタンをクリックすると、アプリケーションは完全に終了します。

于 2011-06-01T04:47:38.000 に答える
17

UIApplicationExitsOnSuspendにプロパティを追加application-info.plistしますtrue

于 2011-07-07T08:14:39.123 に答える
13

いくつかのテストの後、私は次のように言うことができます:

  • プライベートインターフェースを使用[UIApplication sharedApplication]すると、アプリがクラッシュしたように見えますが、- (void)applicationWillTerminate:(UIApplication *)applicationそうする前に呼び出します。
  • を使用exit(0);するとアプリケーションも終了しますが、「通常」に見えます(スプリングボードのアイコンは期待どおりに表示され、ズームアウト効果があります)が、- (void)applicationWillTerminate:(UIApplication *)applicationデリゲートメソッドは呼び出されません。

私のアドバイス:

  1. - (void)applicationWillTerminate:(UIApplication *)applicationデリゲートを手動で呼び出します。
  2. を呼び出しexit(0);ます。
于 2009-05-17T17:00:54.467 に答える
9

ApplicationDelegate は、ユーザーによる意図的な終了の通知を受け取ります。

- (void)applicationWillResignActive:(UIApplication *)application {

この通知を受け取ったら、電話するだけです

        exit(0);

これがすべての作業を行います。そして最高のことは、それはユーザーがやめようとする意図であることです。

私の Audio-App では、音楽がまだ再生されている間に人々がデバイスを同期した後、アプリを終了する必要がありました。同期が完了するとすぐに通知が届きます。しかし、その直後にアプリを終了すると、実際にはクラッシュのように見えます.

その代わりに、次のバックグラウンド アクションでアプリを本当に終了するようにフラグを設定しました。同期後にアプリを更新しても問題ありません。

于 2010-08-12T10:41:15.667 に答える
6

アップルは次のように述べています。

「警告: exit 関数を呼び出さないでください。exit を呼び出すアプリケーションは、適切な終了を実行してホーム画面にアニメーションで戻るのではなく、ユーザーにはクラッシュしたように見えます。」

これは悪い仮定だと思います。ユーザーが終了ボタンをタップして、「アプリケーションは終了します」のようなメッセージが表示された場合、クラッシュしているようには見えません。Apple は、(exit(0) ではなく) アプリケーションを終了する有効な方法を提供する必要があります。

于 2013-05-23T12:01:23.547 に答える
6

文書化されていない方法を使用したため、最近アプリが拒否されました。文字通り:

「残念ながら、プライベート API を使用しているため、App Store に追加できません。非公開 API の使用は、iPhone 開発者プログラム ライセンス契約のセクション 3.3.1 で概説されているように禁止されています。

「3.3.1 アプリケーションは、Apple が規定する方法でのみ文書化された API を使用することができ、プライベート API を使用または呼び出してはなりません。」

アプリケーションに含まれている非公開 API は terminateWithSuccess です」

于 2009-12-02T17:44:36.133 に答える
5

exit(0)アプリケーションがすぐに終了し、アプリがクラッシュしたように見えるため、この関数を直接呼び出さないでください。そのため、ユーザーに確認アラートを表示して、ユーザーが自分でこれを実行できるようにすることをお勧めします。

スウィフト 4.2

func askForQuit(_ completion:@escaping (_ canQuit: Bool) -> Void) {
    let alert = UIAlertController(title: "Confirmation!", message: "Do you want to quit the application", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "Yes", style: UIAlertAction.Style.default, handler: { (action) in
        alert.dismiss(animated: true, completion: nil)
        completion(true)
    }))
    alert.addAction(UIAlertAction(title: "No", style: UIAlertAction.Style.cancel, handler: { (action) in
        alert.dismiss(animated: true, completion: nil)
        completion(false)
    }))
    self.present(alert, animated: true, completion: nil)
}

/// Will quit the application with animation
func quit() {
    UIApplication.shared.perform(#selector(NSXPCConnection.suspend))
    /// Sleep for a while to let the app goes in background
    sleep(2)
    exit(0)
}

使用法:

self.askForQuit { (canQuit) in
     if canQuit {
         self.quit()
     }
}
于 2019-06-18T10:07:30.420 に答える
4

これは良い答えを得ましたが、少し拡張することにしました:

Apple の iOS ヒューマン インターフェイス ガイドラインをよく読まずに、アプリケーションを AppStore に受け入れてもらうことはできません。(彼らは、彼らに対して何かをしたことであなたを拒否する権利を保持します)セクション「プログラムで終了しないでください」http://developer.apple.com/library/ios/#DOCUMENTATION/UserExperience/Conceptual/MobileHIG/UEBestPractices/UEBestPractices。 html は、この場合の扱い方の正確なガイドラインです。

Apple プラットフォームに問題があり、解決策が簡単に見つからない場合は、HIG に相談してください。Apple があなたにそれをしてほしくないという可能性もあり、彼らは通常 (私は Apple ではないので、常に保証はできません) 彼らのドキュメントでそう言っています。

于 2011-02-03T15:23:48.220 に答える
3

たとえば、アプリケーションがインターネット接続を必要とする場合、アプリケーションを「終了する必要がある」場合があります。アラートを表示してから、次のようにすることができます。

if ([[UIApplication sharedApplication] respondsToSelector:@selector(terminate)]) {
    [[UIApplication sharedApplication] performSelector:@selector(terminate)];
} else {
    kill(getpid(), SIGINT); 
}
于 2008-12-11T01:55:15.273 に答える
2

上記に加えて、良い答えを付け加えたいと思います。あなたの記憶をきれいにすることを考えてください。

アプリケーションが終了すると、iPhone OSはアプリケーションに残っているものをすべて自動的にクリーンアップするため、すべてのメモリを手動で解放すると、アプリケーションの終了にかかる時間が長くなる可能性があります。

于 2008-12-10T14:04:15.663 に答える
2
- (IBAction)logOutButton:(id)sender
{
   //show confirmation message to user
   CustomAlert* alert = [[CustomAlert alloc] initWithTitle:@"Confirmation" message:@"Do you want  to exit?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
   alert.style = AlertStyleWhite;
   [alert setFontName:@"Helvetica" fontColor:[UIColor blackColor] fontShadowColor:[UIColor clearColor]];
   [alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{

   if (buttonIndex != 0)  // 0 == the cancel button
   {
      //home button press programmatically
      UIApplication *app = [UIApplication sharedApplication];
      [app performSelector:@selector(suspend)];
      //wait 2 seconds while app is going background
      [NSThread sleepForTimeInterval:2.0];
      //exit app when app is in background
      NSLog(@"exit(0)");
      exit(0);
  }
}
于 2013-09-17T11:56:38.873 に答える
1

上記の [[NSMutableArray new] addObject:nil] アプローチを使用して、明確な exit(0) 関数呼び出しを行わずにアプリを強制終了 (クラッシュ) しました。

なんで?私のアプリは、すべてのネットワーク API 呼び出しで証明書のピン留めを使用して、中間者攻撃を防ぐためです。これらには、金融アプリが起動時に行う初期化呼び出しが含まれます。

証明書認証が失敗すると、すべての初期化呼び出しがエラーになり、アプリが不確定な状態になります。ユーザーが家に帰ってからアプリに戻っても、OS によってアプリが消去されない限り、まだ初期化されておらず、信頼できないため、役に立ちません。

したがって、この 1 つのケースでは、アプリが安全でない環境で動作していることをユーザーに通知するアラートをポップし、ユーザーが [閉じる] をクリックしたときに、前述の方法を使用してアプリを強制終了するのが最善であると判断しました。

于 2015-11-24T23:44:08.760 に答える
1
[[UIApplication sharedApplication] terminateWithSuccess];

それは正常に機能し、自動的に呼び出します

- (void)applicationWillTerminateUIApplication *)application delegate.

コンパイル時の警告を削除するには、このコードを追加します

@interface UIApplication(MyExtras)
  - (void)terminateWithSuccess;
@end 
于 2009-11-05T15:01:05.200 に答える
0

アプリをいつ終了するかは、ユーザーが決定する必要があります。アプリが終了したときのユーザー インタラクションは適切ではないと思います。そのため、適切な API はありません。ホーム ボタンだけに API があります。

エラーがある場合: 改善するか、ユーザーに通知します。再起動が必要な場合: ユーザーに通知するよりも適切に実装します。

ばかげているように聞こえますが、ユーザーに決定させたり、通知したりせずにアプリを終了するのは悪い習慣です。また、ユーザー インタラクション用のホーム ボタンがあるため、Apple は、同じ機能 (アプリの終了) に 2 つのボタンを使用するべきではないと述べています。

于 2013-09-30T09:53:07.067 に答える
0

たとえば、位置情報の更新を取得するために (位置情報の更新のバックグラウンド機能を使用して)、アプリがバックグラウンドでも実行される長期間存続するアプリである場合は、アプリを終了することが適切な場合があります。

たとえば、ユーザーが位置情報ベースのアプリからログアウトし、ホーム ボタンを使用してアプリをバックグラウンドにプッシュしたとします。この場合、アプリは実行し続ける可能性がありますが、完全に終了することが理にかなっている場合があります。これは、ユーザーにとっても (使用する必要のないメモリやその他のリソースを解放する)、アプリの安定性にも役立ちます (つまり、可能な場合にアプリを定期的に再起動することは、メモリ リークやその他のメモリ不足に対するセーフティ ネットです)。問題)。

これは、次のような方法で実現できます (おそらくそうすべきではありませんが、以下を参照してください :-):

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    if (/* logged out */) {
        exit(0);
    } else {
       // normal handling.
    }
}

その後、アプリはバックグラウンドから終了するため、次回アプリを実行したときにユーザー インターフェイスが復元されていれば、ユーザーにとっては間違っているように見えず、クラッシュのようにも見えません。つまり、ユーザーにとっては、アプリがバックグラウンドにあるときにシステムが開始したアプリの終了と何ら変わりはありません。

それでも、アプリを終了できることをシステムに知らせるには、より標準的な方法を使用することをお勧めします。たとえば、この場合、GPS が使用されていないことを確認して、位置の更新の要求を停止します。これには、マップ ビューに現在の位置が表示されている場合はそれをオフにすることも含まれます。そうすれば、アプリがバックグラウンドに入ってから数分後 (つまり[[UIApplication sharedApplication] backgroundTimeRemaining])、システムがアプリを終了します。これにより、アプリを終了するコードを使用しなくても、同じ利点がすべて得られます。

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    if (/* logged out */) {
       // stop requesting location updates if not already done so
       // tidy up as app will soon be terminated (run a background task using beginBackgroundTaskWithExpirationHandler if needed).
    } else {
       // normal handling.
    }
}

そしてもちろん、http://developer.apple.com/iphone/library/qa/qa2008/qa1561.htmlexit(0)を参照する他の回答によると、フォアグラウンドで実行される平均的な本番アプリには決して適切ではありません。

于 2015-10-12T16:55:35.503 に答える
0

Swift 4.2 (またはそれ以前)

呼び出されたライブラリDarvinを使用できます。

import Darwin

exit(0) // Here you go

注意: これは iOS アプリケーションでは推奨されません。

これを行うと、クラッシュ ログが取得されます。

于 2019-02-28T09:51:19.610 に答える