Правильный способ выхода из приложения iPhone?

я программирую приложение для iPhone, и мне нужно заставить его выйти из-за определенных действий пользователя. После очистки памяти, выделенной приложением, каков соответствующий метод вызова для завершения приложения?

22 ответов


ты пробовал exit(0)?

кроме того, [[NSThread mainThread] exit], хотя я не пробовал, что это кажется более подходящим решением.


на iPhone нет концепции выхода из приложения. Единственное действие, которое должно заставить приложение выйти, - это нажатие кнопки "Домой" на телефоне, и это не то, к чему разработчики имеют доступ.

согласно Apple, ваше приложение не должно завершаться самостоятельно. Поскольку пользователь не нажал кнопку "Домой", любое возвращение на главный экран создает впечатление, что ваше приложение разбилось. Это запутанное, нестандартное поведение, и его следует избегать.


exit (0) отображается пользователю как сбой, поэтому покажите пользователю сообщение подтверждения. После подтверждения приостановить (главная кнопка нажмите программно) и подождите 2 секунды, пока приложение собирается фон с анимацией, а затем выйти за вид пользователя

-(IBAction)doExit
{
    //show confirmation message to user
    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Confirmation"
                                                 message:@"Do you want to exit?"
                                                delegate:self
                                       cancelButtonTitle:@"Cancel"
                                       otherButtonTitles:@"OK", nil];
    [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
        exit(0);
    }
}

это не совсем способ выйти из программы,но способ заставить людей выйти.

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];

перейти к вашей информации.plist и проверьте ключ "приложение не работает в фоновом режиме". На этот раз, когда пользователь нажимает кнопку home, приложение завершает работу полностью.


Проверьте Q&A здесь:https://developer.apple.com/library/content/qa/qa1561/_index.html

Q: как программно выйти из приложения iOS?

нет API, предусмотренного для изящного завершения приложения iOS.

в iOS пользователь нажимает кнопку Home для закрытия приложений. Если ваше приложение имеет условия, в которых оно не может предоставить свою целевую функцию, рекомендуется отображение предупреждения для пользователя, которое указывает на характер проблемы и возможные действия, которые пользователь может предпринять-включение WiFi, включение служб определения местоположения и т. д. Разрешить пользователю прекратить работу приложения по своему усмотрению.

предупреждение: не называй . Приложения вызова exit появится пользователю, чтобы разбился, а не выполнять изящное завершение и анимацию обратно на главный экран.

кроме того, данные не могут быть сохранены, потому что -applicationWillTerminate: и подобные UIApplicationDelegate методы не будут вызываться, если вы вызываете exit.

если во время разработки или тестирования необходимо прекратить ваше приложение, то


добавить свойство UIApplicationExitsOnSuspend в application-info.plist для истинного


после некоторых тестов, я могу сказать следующее:

  • использование частного интерфейса:[UIApplication sharedApplication] приведет к тому, что приложение будет выглядеть так, как будто оно разбилось, но оно вызовет - (void)applicationWillTerminate:(UIApplication *)application перед этим;
  • используя exit(0); также завершит приложение, но оно будет выглядеть "нормально" (значки трамплина отображаются как ожидалось, с эффектом уменьшения масштаба), но он не будет вызывать - (void)applicationWillTerminate:(UIApplication *)application метод делегата.

мои советы:

  1. вручную вызовите - (void)applicationWillTerminate:(UIApplication *)application на делегат.
  2. вызов exit(0);.

ваш ApplicationDelegate получает уведомление о намеренном выходе пользователя:

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

когда я получаю это уведомление, я просто называю

        exit(0);

который делает всю работу. И самое лучшее, это намерение useres уйти, поэтому это не должно быть проблемой, называя его там.

в моем аудио-приложении было необходимо выйти из приложения после того, как люди синхронизировали свое устройство, пока музыка все еще играла. Как только синхронизация будет завершена получите уведомление. Но выход из приложения сразу после этого будет выглядеть как крах.

поэтому вместо этого я установил флаг, чтобы действительно выйти из приложения при следующем действии backgrounding. Это нормально для обновления приложения после синхронизации.


мое приложение было отклонено недавно bc я использовал недокументированный метод. Буквально:

" к сожалению, его нельзя добавить в App Store, потому что он использует частный API. Использование непубличных API, которые, как указано в разделе 3.3.1 Лицензионного соглашения программы разработчика iPhone запрещено:

"3.3.1 приложения могут использовать только документированные API в порядке, предписанном Apple, и не должны использовать или вызывать какие-либо частные API."

непубличный API это включено в ваше приложение terminateWithSuccess"


Apple говорят:

"предупреждение: не вызывайте функцию выхода. Приложения, вызывающие exit, будут отображаться пользователю как аварийные, а не выполнять изящное завершение и анимацию обратно на главный экран."

Я думаю, что это плохое предположение. Если пользователь нажмет кнопку выхода и появится сообщение, которое скажет что-то вроде: "приложение теперь выйдет.- похоже, он не разбился. Apple должна предоставить действительный способ выхода из приложения (не выход(0)).


Это получило хороший ответ, но решил немного расширить:

вы не можете принять ваше приложение в AppStore, не прочитав рекомендации по человеческому интерфейсу iOS от Apple. (они сохраняют за собой право отвергнуть вас за то, что вы делаете что-нибудь против них) раздел "Не выходите программно" http://developer.apple.com/library/ios/#DOCUMENTATION/UserExperience/Conceptual/MobileHIG/UEBestPractices/UEBestPractices.html является точным руководством в том, как вы должны лечить в этом случае.

Если у вас когда-либо были проблемы с платформой Apple, вы не можете легко найти решение, обратитесь к HIG. Возможно, Apple просто не хочет, чтобы вы это делали, и они обычно (я не Apple, поэтому я не могу гарантировать всегда) говорят об этом в своей документации.


мы не можем выйти из приложения с помощью exit(0), abort() функции, так как Apple настоятельно не рекомендует использовать эти функции. Хотя вы можете использовать эти функции для целей разработки или тестирования.

Если во время разработки или тестирования необходимо прекратить рекомендуется применение, функция abort или макрос assert

пожалуйста, найдите это яблоко Q & A поток для получения дополнительной информации.

Как использовать эту функцию создать впечатление, как приложение сбой. Поэтому у меня есть предложение, как мы можем отобразить предупреждение с сообщением о прекращении для осведомленного пользователя о закрытии приложения из-за недоступности определенных функций.

но руководство по человеческому интерфейсу iOS для Запуск И Остановка Приложения, предполагая, что никогда не используйте кнопку Quit или Close для завершения приложения. Вместо этого они предлагают отобразить правильное сообщение, чтобы объяснить ситуация.

приложение iOS не отображается или выхода. Люди перестают использовать app когда они переключаются на другое приложение, вернуться на главный экран, или положить их устройства в спящем режиме.

никогда не выходите из приложения iOS программно. Люди склонны интерпретировать это как крушение. Если что-то мешает вашему приложению функционировать как предполагалось, что вам нужно рассказать пользователям о ситуации и объяснить, что они могут это сделать.


в дополнение к вышесказанному, хорошо, ответ я просто хотел добавить, подумайте об очистке памяти.

после выхода вашего приложения ОС iPhone автоматически очистит все, что осталось от вашего приложения, поэтому освобождение всей памяти вручную может просто увеличить время, необходимое вашему приложению для выхода.


Hm, возможно, вам "придется" выйти из приложения, если, скажем, вашему приложению требуется подключение к интернету. Вы можете отображать предупреждение, а затем сделать что-то вроде этого:

if ([[UIApplication sharedApplication] respondsToSelector:@selector(terminate)]) {
    [[UIApplication sharedApplication] performSelector:@selector(terminate)];
} else {
    kill(getpid(), SIGINT); 
}

- (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);
  }
}

Я использовал [[NSMutableArray new] addObject:nil] подход, упомянутый выше, чтобы заставить выйти (сбой) приложение без вызова функции контрольного сигнала exit(0).

Почему? Потому что мое приложение использует закрепление сертификатов на всех вызовах сетевого API для предотвращения атак "человек в середине". К ним относятся вызовы инициализации, которые делает мое финансовое приложение при запуске.

Если проверка подлинности сертификата не выполняется, все мои инициализации вызывает ошибку и оставить мое приложение в неопределенном государство. Разрешение пользователю вернуться домой, а затем обратно в приложение не помогает, так как, если приложение не было очищено ОС, оно все еще неинициализировано и ненадежно.

Итак, в этом случае мы сочли, что лучше всего всплывающее предупреждение, информирующее пользователя о том, что приложение работает в небезопасной среде, а затем, когда они нажмут "закрыть", принудительно выйти из приложения с помощью вышеупомянутого метода.


выход из приложения другим способом, чем кнопка home является действительно не iOS-esque подход.

Я сделал этот помощник, хотя, который не использует личные вещи:

void crash()
{ [[NSMutableArray new] addObject:NSStringFromClass(nil)]; }

но все еще не предназначен для производства в моем случае. Это для тестирования отчетов о сбоях или быстрого перезапуска после сброса основных данных. Просто сделал его безопасным, чтобы не быть отклоненным, если функция оставлена в производственном коде.


пользователь должен решить, когда приложение выходит. Я не думаю, что это хорошее взаимодействие с пользователем, когда приложение завершает работу. Поэтому для него нет хорошего API, только кнопка home имеет один.

, Если есть ошибка: реализовать лучше или уведомить Пользователя. Если должен быть перезапуск: реализовать его лучше уведомить Пользователя.

Это звучит глупо, но это плохая практика, чтобы выйти из приложения, не позволяя пользователю решить, и не уведомляя его. И так как есть кнопка home для взаимодействие с пользователем, утверждает Apple, не должно быть 2 вещей для одной и той же функции (выход из приложения).


выход из приложения другим способом

Я сделал этот помощник, хотя, который не использует личные вещи:

выход(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.
    }
}

и конечно, с помощью exit(0) никогда не будет подходящим для среднего производственного приложения, которое работает на переднем плане, согласно другим ответам, которые ссылаются http://developer.apple.com/iphone/library/qa/qa2008/qa1561.html


[[UIApplication sharedApplication] terminateWithSuccess];

Он работал нормально и автоматически называет

- (void)applicationWillTerminateUIApplication *)application delegate.

чтобы удалить предупреждение о времени компиляции, добавьте этот код

@interface UIApplication(MyExtras)
  - (void)terminateWithSuccess;
@end