51

ログアウトボタンが押されたときにiPhoneアプリをプログラムで再起動しようとしています。

共有するコードサンプルを持っている人はいますか? main.m ファイルを変更することで可能であると読みましたが、これに関連するコードは見つかりませんでした。

どんな助けでも大歓迎です。

4

7 に答える 7

66

ノート:

これは「不可能」と答えられていますが、新しいiOS開発者が尋ねるのは有効な質問であり、彼らができることはおそらく彼らが望んでいることだと思います。

iOSアプリを技術的に再起動または終了するのではなく、ユーザーの観点からアプリを「再起動」する方法があります。他の回答で指摘されているように、iOSでは許可されていないため、iOSアプリを明示的に終了しないでください。

私の答え:

アプリを起動時の状態に戻したい場合、これは100%可能ではありませんが、すべての有効な目的に十分な方法のほとんどをそこに到達させる方法を説明します。

最初に行うことは、ルートビューコントローラーを再作成することです。次のようなアプリデリゲートのメソッドからこれを行うことをお勧めします。

- (void)resetAppToFirstController
{
    self.window.rootViewController = [[MyMainViewController alloc] initWithNibName:nil bundle:nil];
}

多くの場合、これで十分ですが、このメソッドでは、使用しているアプリの状態もリセットする必要があります。たとえば、ユーザーをログアウトし、非永続状態をリセットし、可能なすべてのオブジェクトを無効化(解放)します。このメソッドを使用して、から最初のViewControllerを最初に作成することもできますapplication:didFinishLaunchingWithOptions

フレームワーククラスとシングルトン:

次のようなフレームワークシングルトンまたはアプリごとのインスタンスの状態を完全にリセットすることはできません。

[UIApplication sharedApplication];
[NSNotificationCenter defaultCenter];
[NSUserDefaults standardUserDefaults];
[UIScreen screens];
// etc...

とにかく非永続状態をこれらに保存するべきではないので、これはおそらく問題ありません(ただしNSNotificationCenter、オブジェクトが解放されたときに、登録されたすべてのオブザーバーが削除されている必要があります)。resetAppToFirstControllerフレームワークの状態を初期化またはリセットする場合は、同じ方法で行うことができます。windowとにかく、これらやオブジェクトを再作成する必要はありません。

独自のシングルトンがある場合は、それらをシングルトンホルダークラス(それ自体が実際のシングルトン)に格納することで、これらを再作成できます。概念的には、これは他の各シングルトンのプロパティとresetそれらすべてを無効にして解放する方法。他のシングルトンは、(静的変数またはグローバル変数の代わりに)このクラスを使用してシングルトンインスタンスを格納する必要があります。サードパーティのライブラリもシングルトンを使用している可能性があるため、サードパーティのライブラリを使用する場合は注意してください。必要に応じてリセットできるように、これらもシングルトンホルダーを使用するようにする必要があります。とにかく、この手法は良い習慣だと思います。場合によっては(単体テストなど)、通常はシングルトンであるオブジェクトを削除して、元の状態に再初期化する必要があるためです。ただし、シングルトン実装をシングルトンホルダーと結合したくないので、これを実装する良い方法はNSMutableDictionary、に関連付けられたオブジェクトとしてを使用することです。[UIApplication sharedApplication]シングルトンクラス名をキーとして使用します。ただし、これはこの質問の範囲を超えたより高度な手法であるため、トピックから少し外れます。


上記は、ユーザーに関する限り、アプリケーションを「リセット」するのに十分なはずです。最初のビューコントローラとして必要な場合は、スプラッシュ画面を再度表示することもできます。

于 2012-11-11T12:06:29.683 に答える
20

まず第一に、アプリを強制終了することは可能ですが、これは Apple によって許可されておらず、拒否されます。拒否されなかったとしても、いったん強制終了されたアプリを再起動する方法はありません。前述のように、コードを使用してアプリをリセットする方法を見つける必要がありますJason Coco。手間がかかるかもしれませんが、Apple に拒否されないためには、それだけの価値があります。

于 2010-12-09T16:46:28.487 に答える
15

これを試してみてください、それは私のために働きます。

-(void)restart
{
    MyAppDelegate *appDelegate = (MyAppDelegate *)([UIApplication sharedApplication].delegate);
    [appDelegate.navigationController popToRootViewControllerAnimated:NO];
    UIViewController *topViewController = appDelegate.navigationController.topViewController;
    Class class = [topViewController class];
    NSString *nibName = topViewController.nibName;
    UIViewController *rootViewcontroller = (UIViewController *)([[class alloc] initWithNibName:nibName bundle:nil]);
    [appDelegate.navigationController.view removeFromSuperview];
    appDelegate.navigationController.viewControllers = [NSArray arrayWithObject:rootViewcontroller];
    [appDelegate.window addSubview:appDelegate.navigationController.view];
    [appDelegate.window makeKeyAndVisible];
}
于 2012-01-04T18:20:49.497 に答える
8

目的 C:

exit(0);

迅速:

exit(0)

私はこれを 2 つのライブ アプリで使用していますが、拒否されたことはありません。私のアプリの 1 つには、アプリのホームページの機能としてこのコード行さえあります。Twitterのツイートボタンがある右上隅にあります。したがって、予期しないクラッシュのように見えない限り、Apple が拒否することを心配する必要はありません。

ここに画像の説明を入力

于 2015-08-31T15:44:13.163 に答える
5

プライベート API を使用してシミュレーターでこれを行う方法は次のとおりです。

    NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@", scheme, endpointString]];

    Class pClass = NSClassFromString(@"BKSSystemService");
    id service = [[pClass alloc] init];

    SEL pSelector = NSSelectorFromString(@"openURL:application:options:clientPort:withResult:");
    NSMethodSignature *signature = [service methodSignatureForSelector:pSelector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    invocation.target = service;
    NSString *app = @"com.apple.mobilesafari";
    [invocation setSelector:pSelector];
    [invocation setArgument:&URL atIndex:2];
    [invocation setArgument:&app atIndex:3];
    unsigned int i = [service performSelector:NSSelectorFromString(@"createClientPort")];
    [invocation setArgument:&i atIndex:5];
    [invocation invoke];
    exit(0);

これは、適切な資格を持つジェイルブレイクされたアプリでも機能するはずです。

他のアプリでは、単純な HTML ページを使用できます。

    NSString *format = @"https://dl.dropboxusercontent.com/s/rawt1ov4nbqh4yd/launchApp.html?scheme=%@&URL=%@";
    NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:format, scheme, endpointString]];
    [[UIApplication sharedApplication] openURL:URL];
    exit(0);

残念ながら、この場合はインターネット接続が必要です。

于 2015-04-08T11:32:53.673 に答える