Подтвердить что ты не робот

Попытка отклонить UIAlertController с неизвестным ведущим

Мое приложение разбилось, и это должно быть из-за UIAlertController.

Эта проблема возникает только в iOS 8.x, где доступен UIAlertController. Странный факт заключается в том, что мое приложение не использует UIAlertViewController или UIAlertView.

Отчеты говорят мне:

Trying to dismiss UIAlertController <UIAlertController: 0x172c5d80> with unknown presenter.

Как это может случиться?

Я думал о

  • Отменить систему AlertView, отображаемую благодаря жесту встряхивания
  • WebView освобожден, когда приглашение или общий диалог все еще находятся на экране
  • Предупреждение о низком уровне заряда аккумулятора

но ни один из этих случаев не приведет меня к сбою.

Что мне сообщает журнал сбоев, так это то, что ОС показывает AlertView, который будет прикреплен к моему окну приложения, а в некоторых случаях потеряет родительский контроллер представления, который представил UIAlertViewController.

Любые идеи, как найти проблему?

Здесь трассировка стека

_________________________________
0    CoreFoundation                         0x2bc0c45f __exceptionPreprocess + 127
1    libobjc.A.dylib                        0x39c79c8b objc_exception_throw + 36
2    CoreFoundation                         0x2bc0c3a5 +[NSException raise:format:] + 110
3    UIKit                                  0x2f4ad13d -[UIAlertController _dismissAnimated:triggeringAction:triggeredByPopoverDimmingView:] + 414
4    UIKit                                  0x2f4acf97 -[UIAlertController _dismissAnimated:triggeringAction:] + 28
5    UIKit                                  0x2f590a0b -[_UIAlertControllerActionView touchesEnded:withEvent:] + 160
6    UIKit                                  0x2f159567 -[UIWindow _sendTouchesForEvent:] + 520
7    UIKit                                  0x2f152e31 -[UIWindow sendEvent:] + 542
8    UIKit                                  0x2f129759 -[UIApplication sendEvent:] + 194
9    UIKit                                  0x2f39d2f9 _UIApplicationHandleEventFromQueueEvent + 14166
10   UIKit                                  0x2f1281a9 _UIApplicationHandleEventQueue + 1350
11   CoreFoundation                         0x2bbd2fbf __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 12
12   CoreFoundation                         0x2bbd23cf __CFRunLoopDoSources0 + 216
13   CoreFoundation                         0x2bbd0a35 __CFRunLoopRun + 770
14   CoreFoundation                         0x2bb1e3b1 CFRunLoopRunSpecific + 474
15   CoreFoundation                         0x2bb1e1c3 CFRunLoopRunInMode + 104
16   GraphicsServices                       0x3308d201 GSEventRunModal + 134
17   UIKit                                  0x2f18843d UIApplicationMain + 1438
18   MyApp                                  0x00028a07 main (main.mm:16)

ИЗМЕНИТЬ

отверстия спросили о моей инициализации окна. Здесь код моего AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[MyAppCustomWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    _mainViewController = [[MyAppContainerViewController alloc] initWithNibName:nil bundle:nil];
    _mainStatusBarVC = [[MyAppStatusBarVC alloc] initWithRootVC:_mainViewController];

    [self.window setRootViewController:_mainStatusBarVC];
    [self.window makeKeyAndVisible];

    return YES;
}
4b9b3361

Ответ 1

Я уверен, ваш авария произошла на iPad.

На iPad, с iOS8, UIActionSheet, похоже, обрабатывается с помощью UIAlertController

С помощью этого кода

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if(buttonIndex == 1) return; // Cancel button

    [self doSomeViewControllerDismisses];
}

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

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if(buttonIndex == 1) return; // Cancel button

    dispatch_async(dispatch_get_main_queue(), ^{
        [self doSomeViewControllerDismisses];
    });
}

Ответ 2

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

Общим средством для этого является представление или увольнение контроллеров в UIAlertViewDelegate alertView: didDismissWithButtonIndex: метод, с тех пор вы уверены, что ведущий не уйдет во время любого увольнения.

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

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

Ответ 3

попробуйте отключить основной поток Alertview, используя Block on main thrad.

dispatch_async(dispatch_get_main_queue(), { () -> Void in
  //  Write your alert view code in swift language .
})