UIAlertView завершает работу с ошибкой EXC_BAD_ACCESS

У меня такая ошибка: когда я нажимаю navigationbar.backItemButton, я показываю UIAlertView с двумя кнопками. Когда я нажимаю на любой из них, приложение завершается только с EXC_BAD_ACCESS. Метод - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex не вызывается. Как я могу это решить? Спасибо!

//h - файл

@interface DetailsTableViewController : UITableViewController <UITextFieldDelegate, UIAlertViewDelegate>

//м - файл

- (void)viewWillDisappear:(BOOL)animated
{
    //if changes unsaved - alert reask window
    if (isDirty)
    {
        UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Save changes?"  
                                                      message:@"Press YES if you want to save changes before exit, NO - other case."  
                                                     delegate: self  
                                                    cancelButtonTitle: @"NO"  
                                                    otherButtonTitles: @"YES", nil];   

        [message show];  

        [message autorelease];
    }   
}

    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    NSString *title = [alertView buttonTitleAtIndex: buttonIndex];  

    if([title isEqualToString: @"YES"])  
    {  
        [self saveBtnUserClick];    
    } 
}

person yozhik    schedule 18.11.2010    source источник


Ответы (5)


Я думаю, проблема в том, что после того, как вы нажали кнопку «Назад», ваш текущий контроллер удаляется из стека навигации и освобождается, поэтому, когда предупреждение пытается вызвать свои методы делегата, оно вызывает их для освобожденного объекта, что приводит к ошибке EXC_BAD_ACCESS. Для обхода проблемы вижу 2 очевидных варианта (хотя могут быть и лучшие решения):

  1. Дополнительно сохраните свой контроллер где-нибудь (может быть, в предыдущем контроллере), но вам нужно найти способ освободить его, когда вы закончите.
  2. Создайте свою пользовательскую кнопку вместо стандартной «назад» и просто покажите предупреждение при ее нажатии. Затем в методе делегата оповещения извлеките текущий контроллер из стека навигации.
person Vladimir    schedule 18.11.2010
comment
Ты был прав! Звонил диаллок. Я пытался [self.tableView сохранить]; и [самоудержание]; но все равно вылетает. Мне нужна не левая кнопка, а backItemButton. Есть ли решения для этого? Спасибо. - person yozhik; 18.11.2010
comment
Я решил эту проблему, как вы сказали, с помощью leftItemButton. Спасибо! - person yozhik; 18.11.2010

Попробуйте изменить делегата на ноль вместо себя. Это решило мою проблему.

person Harikrishnan    schedule 01.02.2013

Ваш контроллер представления реализует UIAlertViewDelegate? Если нет, добавьте объявление интерфейса до того, как { запустится.

Также попробуйте NSLogging внутри метода clickedButtonAtIndex и распечатайте значения buttonIndex и посмотрите консоль.

Изменить: снова читая свой пост, я думаю, вы действительно пропустили UIAlertViewDelegate в своем объявлении интерфейса.

person Bourne    schedule 18.11.2010
comment
ах, я вижу, вы отредактировали это. Раньше его не было, поэтому я ошибся. Думаю, теория Владимира выглядит очень правдоподобно. Проверьте это. - person Bourne; 18.11.2010

Возможно [авторелиз сообщения]; вы ошибаетесь? используйте [выпуск сообщения];

Поскольку вы использовали [[UIAlertView alloc] init.....]; там для вас должны освободить память.

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

Наслаждаться.

person Amitesh Kumar    schedule 18.11.2010
comment
Возможно [авторелиз сообщения]; вы ошибаетесь? используйте [выпуск сообщения]; Я пробовал. - person yozhik; 18.11.2010

«Попробуйте изменить делегата на nil вместо себя. Это решило мою проблему». работал у меня. спасибо

person Vinicius Souza    schedule 18.11.2013