Приложение tvOS — UIAlertController аварийно завершает работу с UIAlertAction

У меня есть приложение tvOS с одним видом. Он имеет представление коллекции с 24 ячейками представления коллекции. Когда выбрана ячейка представления коллекции, я запускаю предупреждение. Я использую код по умолчанию из справочной документации Apple (вставлен ниже).

 UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"My Alert"
                                               message:@"This is an alert."
                                               preferredStyle:UIAlertControllerStyleAlert];

 UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" 
                                               style:UIAlertActionStyleDefault
                                               handler:^(UIAlertAction * action) {}];

[alert addAction:defaultAction]; // This is what I comment out
[self presentViewController:alert animated:YES completion:nil];

Когда я не добавляю действие по умолчанию в оповещение (закомментируйте [alert addAction:defaultAction];), оповещение отображается правильно, но невозможно его отклонить. Когда я добавляю defaultAction к предупреждению, предупреждение отображается с кнопкой «ОК», но я получаю ужасную ошибку SIGABRT, как только она появляется на экране.

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: '-[_UIAlertControllerActionView image]: unrecognized selector
 sent to instance 0x7fe571ddee10'

Трассировка стека здесь:

2015-11-10 19:42:02.927 AppABC[1701:97632] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_UIAlertControllerActionView image]: unrecognized selector sent to instance 0x7fefd3ddaf10'
*** First throw call stack:
(
0   CoreFoundation                      0x000000010de0a0b5 __exceptionPreprocess + 165
1   libobjc.A.dylib                     0x000000010d884deb objc_exception_throw + 48
2   CoreFoundation                      0x000000010de126dd -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3   CoreFoundation                      0x000000010dd6005a ___forwarding___ + 970
4   CoreFoundation                      0x000000010dd5fc08 _CF_forwarding_prep_0 + 120
5   IsItGood                            0x000000010d381170 __82-[ViewController collectionView:didUpdateFocusInContext:withAnimationCoordinator:]_block_invoke78 + 48
6   UIKit                               0x000000010e260df4 +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 582
7   UIKit                               0x000000010e2612ec +[UIView(UIViewAnimationWithBlocks) animateWithDuration:animations:] + 63
8   IsItGood                            0x000000010d380ca8 -[ViewController collectionView:didUpdateFocusInContext:withAnimationCoordinator:] + 536
9   UIKit                               0x000000010ea24e09 -[UICollectionView _didUpdateFocusInContext:withAnimationCoordinator:] + 1181
10  UIKit                               0x000000010eb15a5e _UIFocusEnvironmentDidUpdateFocus + 628
11  UIKit                               0x000000010e4fe102 __36-[UIScreen _updateFocusWithContext:]_block_invoke + 88
12  UIKit                               0x000000010e4fe161 __36-[UIScreen _updateFocusWithContext:]_block_invoke + 183
13  UIKit                               0x000000010e4fdb9f -[UIScreen _updateFocusWithContext:] + 1912
14  UIKit                               0x000000010e4feca9 -[UIScreen updateFocusIfNeeded] + 597
15  UIKit                               0x000000010e1c1e4a _runAfterCACommitDeferredBlocks + 317
16  UIKit                               0x000000010e1d53d9 _cleanUpAfterCAFlushAndRunDeferredBlocks + 95
17  UIKit                               0x000000010e1e1312 _afterCACommitHandler + 90
18  CoreFoundation                      0x000000010dd35ab7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
19  CoreFoundation                      0x000000010dd35a27 __CFRunLoopDoObservers + 391
20  CoreFoundation                      0x000000010dd2b67b __CFRunLoopRun + 1147
21  CoreFoundation                      0x000000010dd2af78 CFRunLoopRunSpecific + 488
22  GraphicsServices                    0x0000000111582ad2 GSEventRunModal + 161
23  UIKit                               0x000000010e1b608d UIApplicationMain + 171
24  AppABC                              0x000000010d3826af main + 111
25  libdyld.dylib                       0x000000011050d9e9 start + 1
26  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Какие-нибудь мысли??


person Dan Cohen    schedule 07.11.2015    source источник
comment
Можете ли вы опубликовать трассировку стека исключения?   -  person Justin Voss    schedule 10.11.2015
comment
@JustinVoss сократил трассировку стека, поскольку я не получаю много символов в комментариях ... - *** Завершение приложения из-за необработанного исключения «NSInvalidArgumentException», причина: «- [_UIAlertControllerActionView image]: нераспознанный селектор отправлен в экземпляр 0x7f88a0e287d0» *** Стек вызовов первого броска: ( 1 libobjc.A.dylib 0x0000000107176deb objc_exception_throw + 48 .... 25 libdyld.dylib 0x0000000109dff9e9 start + 1 26 ??? 0x00000000000000001 0x0 + 1 ) libc++abi.dylib завершает работу с помощью исключение типа NSException   -  person Dan Cohen    schedule 10.11.2015
comment
Да, контекста недостаточно, чтобы помочь. Вы должны отредактировать свой вопрос, чтобы включить полную трассировку стека.   -  person Justin Voss    schedule 10.11.2015


Ответы (3)


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

Посмотрите на свою реализацию -[ViewController collectionView:didUpdateFocusInContext:withAnimationCoordinator:] и посмотрите, где вы вызываете image для чего-то: похоже, вы предполагаете, что объект относится к одному типу, когда на самом деле это другой.

person Justin Voss    schedule 11.11.2015
comment
Ты совершенно прав. Я анимирую недавно сфокусированную коллекцию viewcell. Однако, когда я представляю предупреждение, новое сфокусированное представление является предупреждением, которое не имеет изображения, метки названия фильма и т. д. Большое спасибо!! - person Dan Cohen; 11.11.2015

Я попробовал ваш код и создал новое приложение с одним представлением, с одной кнопкой и одним действием кнопки. Действие кнопки содержит фрагмент вашего кода:

- (IBAction)action:(id)sender {


    UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"My Alert"
                                                                   message:@"This is an alert."
                                                            preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK"
                                                            style:UIAlertActionStyleDefault
                                                          handler:^(UIAlertAction * action) {}];

    [alert addAction:defaultAction]; // This is what I comment out
    [self presentViewController:alert animated:YES completion:nil];
}

Он работает нормально. Ошибка должна возникнуть после закрытия UIAlertViewController (это делается автоматически после нажатия OK). Эта часть кода отсутствует. Добавьте точки останова во все соответствующие части вашего кода и проверьте, где он продолжает отслеживать эту ошибку.

person Stefan    schedule 09.11.2015
comment
Я знаю, что код Apple работает. Я также попробовал это в тестовом пустом приложении tvOS и работает так, как предполагалось. К сожалению, у меня нет возможности нажать кнопку «ОК». Приложение вылетает до того, как позволяет мне щелкнуть по нему. - person Dan Cohen; 10.11.2015
comment
Он вылетает прямо в строке, которую вы закомментировали? - person Stefan; 10.11.2015
comment
Нет, происходит сбой при выполнении [self presentViewController:alert анимированный:YES завершение:ноль]; - person Dan Cohen; 11.11.2015

Я написал три разных примера

import UIKit

class FirstViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    @IBAction func alertDone(sender: AnyObject) {
        let title = "Download Complete"
        let message = "Your game download completed"

        let buttonTitle = "OK"

        let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)

        let doneAction = UIAlertAction(title: buttonTitle, style: UIAlertActionStyle.Default) { _ in
            print("Done was pressed")
        }

        alert.addAction(doneAction)

        presentViewController(alert, animated: true, completion: nil)

    }


    @IBAction func alertError(sender: AnyObject) {
        let title = "Error Complete"
        let message = "Please try again later."

        let okButton = "OK"
        let retryButton = "Retry Download"

        let alertError = UIAlertController(title: title, message: message, preferredStyle: .Alert)
        let okAction = UIAlertAction(title: okButton, style: .Default, handler: nil)

        let retryAction = UIAlertAction(title: retryButton, style: .Cancel) { _ in
            print("Retry was pressed")
        }

        alertError.addAction(okAction)
        alertError.addAction(retryAction)

        presentViewController(alertError, animated: true, completion: nil)


    }

    @IBAction func alertConfirm(sender: AnyObject) {
        let title = "Are you sure"
        let message = "Please try again later."

        let cancelButton = "Cancel"
        let deleteButton = "Delete"

        let alertError = UIAlertController(title: title, message: message, preferredStyle: .Alert)
        let cancelAction = UIAlertAction(title: cancelButton, style: .Default, handler: nil)

        let deleteAction = UIAlertAction(title: deleteButton, style: .Cancel) { _ in
            print("Retry was pressed")
        }

        alertError.addAction(cancelAction)
        alertError.addAction(deleteAction)

        presentViewController(alertError, animated: true, completion: nil)

    }

}
person Durul Dalkanat    schedule 28.11.2015