UIAlertView не отображается и приводит к ошибке «EXC_BAD_ACCESS»

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

Редактировать Ниже приведен полный метод (ранее отображался частично). Когда я закомментирую все доUIAlertView и подставьте строку @ "test" вместо передачи сообщения, предупреждение отображается успешно. Я неправильно обрабатываю память своей структурой?

- (IBAction)joinButton {
    struct userInfo localUser;

    [emailAddress resignFirstResponder];

    //convert textField text to char array in structure
    localUser.firstName = [self convertStringtoCharArray:firstName.text];
    localUser.lastName = [self convertStringtoCharArray:lastName.text];
    localUser.username = [self convertStringtoCharArray:username.text];
    localUser.email = [self convertStringtoCharArray:emailAddress.text];
    localUser.ipAddress = [self convertStringtoCharArray:localIPAddress.text];
    localUser.latitude = currentLocation.coordinate.latitude;
    localUser.longitude = currentLocation.coordinate.longitude;

    //pass structure to be sent over socket
    int result = [myNetworkConnection registerWithServer:&localUser];

    NSString *message = nil;

    //process result of sending attempt
    if (result == 0) {
        //registration succesful
        message = [NSString stringWithString:@"Registration successful"];
    } else if (result == 1) {
        //server unavailable
        message = [NSString stringWithString:@"Server unavailable. Please check your wi-fi settings and try again."];
    } else if (result == 2) {
        //unable to establish connection
        message = [NSString stringWithString:@"Unable to communicate with server. Please check your wi-fi settings and try again."];
    } else if (result == 3) {
        //username already in use
        message = [NSString stringWithString:@"Username in use. Try another username."];
    }

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Registration"
                                                    message:message
                                                   delegate:nil 
                                          cancelButtonTitle:@"Ok" 
                                          otherButtonTitles:nil];

    [alert show];
    [alert release];
}

Когда я выполняю код, который iPhone выдает, как будто он собирается отобразить предупреждение, но вылетает. Я получаюEXC_BAD_ACCESS ошибка в консоли. Я правильно не выпускаю ни предупреждение, ни сообщение? Вот вывод консоли:

Program received signal:  “EXC_BAD_ACCESS”.
(gdb) backtrace
#0  0x30011944 in objc_msgSend ()
#1  0x3054803e in NSPopAutoreleasePool ()
#2  0x3054c808 in -[NSAutoreleasePool release] ()
#3  0x30936ac4 in _UIApplicationHandleEvent ()
#4  0x3204696c in PurpleEventCallback ()
#5  0x30254a76 in CFRunLoopRunSpecific ()
#6  0x3025416a in CFRunLoopRunInMode ()
#7  0x320452a4 in GSEventRunModal ()
#8  0x308f037c in -[UIApplication _run] ()
#9  0x308eea94 in UIApplicationMain ()
#10 0x000020bc in main (argc=1, argv=0x2ffff508) at /Users/reu2009/Documents/iPhone Development/Development/BuddyTracker/main.m:14
(gdb) frame 10
#10 0x000020bc in main (argc=1, argv=0x2ffff508) at /Users/reu2009/Documents/iPhone Development/Development/BuddyTracker/main.m:14 14       int retVal = UIApplicationMain(argc, argv, nil, nil);

Редактировать удален[message release]; и назначенные строки с помощью[NSString stringWithString]; на основе ответов.

 Eric de Araujo06 июл. 2009 г., 22:28
Это происходит в самом конце метода. Кажется, вы правы, Кен, это что-то ранее в методе (см. Последнее редактирование).
 Eric de Araujo06 июл. 2009 г., 20:57
No. та же ошибка. Я даже закомментировал блок создания условного сообщения.
 Ken Pespisa07 июл. 2009 г., 01:11
Попытайтесь добавить точку останова в верхней части вашего метода. Затем используйте шаг в опцию, чтобы пройти через каждую строку. Вы сузили его до чего-то выше линии UIAlertView, но все еще слишком трудно понять, в чем проблема. В зависимости от того, на какой линии находится отладчик, когда появляется сообщение EXC-BAD-ACCESS, это будет ваша проблемная строка. Хорошее видео об основах отладки смотрите в блоге Джеффа Ламарша об отладке: Iphonedevelopment.blogspot.com / 2009/03 / debugging.html
 Ken Pespisa06 июл. 2009 г., 20:44
работает, если вы заменяете message: message на message: @ "test"?
 Ken Pespisa06 июл. 2009 г., 22:22
Очень странно. Вы пытались пройти через отладчик, чтобы выяснить, на какой линии происходит ошибка? Мне просто любопытно, ищем ли мы не в том месте.

Ответы на вопрос(6)

возвращаемые конструкторами удобства, уже настроены на автоматический выпуск. Хотя вы объявили указатель на «message», сам объект «message» вам не принадлежит, поскольку вы использовали вспомогательный конструктор @ «string» для создания объекта NSString. Таким образом, вам не нужно выпускать его.

Когда вы отпускаете его вручную, он выходит слишком много раз (один раз вручную и один раз, когда происходит процесс автоматического выпуска) и выдает ошибку.

Вот дополнительная информация от Apple:

http: //developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.htm

Хорошее практическое правило: если вы не используете один из методов alloc, init или copy для создания объекта (или если вы сохраняете объект самостоятельно), вам не нужно его освобождать, но вы можете полагаться на метод, который фактически его создал чтобы сделать эту работу для вас.

 Eric de Araujo06 июл. 2009 г., 20:53
Спасибо за это. Однако после удаления [выпуск сообщения]; Я получаю ту же ошибку. Это должно быть что-то за пределами освобождения строки сообщения.
 Sean McMains06 июл. 2009 г., 20:59
Ну, тогда я сбит с толку. :) Я бы попробовал предложение Кена и, возможно, закомментировал строку «int result ...», чтобы увидеть, может ли какой-либо из них повлиять на проблему так или иначе.
 Mark06 июл. 2009 г., 21:01
Я считаю, что правило заключается в том, что методы, содержащие alloc, retain или copy, требуют, чтобы вы освободили объект.
 Eric de Araujo06 июл. 2009 г., 21:05
Ни замена строки сообщения, ни комментирование строки «int result» не приводят к отображению предупреждения. Может ли это быть что-то, что вызывается после «возврата» на клавиатуре? Я вызвал [текстовое поле resignFirstResponder]; но будет ли видимая клавиатура вызывать тревогу?
 Sean McMains06 июл. 2009 г., 21:07
Добавлена заметка о сохранении объекта. Спасибо, Марк!

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

ClassA

...

doSomething {
 ... some stuff ...

 [MyAlertView showAlert];

 ... some other stuff...

}

Что я подозреваю, так это то, что, когда я щелкаю по кнопке, объект оповещения отображается асинхронно.

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

Моим окончательным решением было объявить переменную в родительском представлении и освободить ее с другими переменными, когда представление освобождено.

... вызывал его из основного потока

 a1phanumeric15 нояб. 2012 г., 12:39
Это была моя проблема. Благодарность
 Ben Wheeler12 июн. 2013 г., 22:05
Для примера того, что означает j2emanue, смотрите / Stackoverflow.com вопросы / 12468677 / ...

Я решил это так

UIAlertView *alertMSG = [[UIAlertView alloc] initWithTitle:nil
                        message:@"Your mnessage here"
                        delegate:self
                        cancelButtonTitle:@"Title here"
                        otherButtonTitles: nil];

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
         [alertMSG show];
    }];

Войдите в информацию о вашем исполняемом файле. Нажмите на вкладку Аргументы. Нажмите + на «Переменные для установки в среде». Тип NSZombieEnable и ДА.

Когда освободится память, которая уже была освобождена, NSZombie отобразит адрес, затем вы можете использовать Инструменты, чтобы найти реальный объект. Домик Корбина имеет хороший обзор того, как это сделать: Инструменты на Leopard: как отладить эти случайные сбои в приложении Какао

потому что вы никогда не сохраняете объект сообщения.

Вместо того, чтобы просто сказатьmessage = @"string", тебе нужно сказатьmessage = [NSString stringWithString:@"string"]; Честно говоря, я не уверен, почему (возможно, кто-то может прокомментировать, и я могу улучшить этот пост!), Но это должно сработать.

 davidcann10 февр. 2010 г., 08:03
Я уверен, что они делают то же самое ...@"string" а также[NSString stringWithString:@"string"] оба возвращают не сохраненные строки NSS.

Ваш ответ на вопрос