UIAlertView появляется три раза за вызов вместо одного раза

StackOverflow https://stackoverflow.com/questions/2273283

  •  20-09-2019
  •  | 
  •  

Вопрос

Я получаю странное поведение от NSAlert в двух разных частях моей программы.Поведение такое:

  1. Появляется предупреждение, а затем спонтанно исчезает.
  2. Оповещение появляется снова, а затем остается до тех пор, пока оно не будет закрыто пользователем, т.е.нормальное поведение.
  3. Оповещение появляется снова.

Такое поведение происходит только при первом вызове метода, отображающего предупреждение.После первого раза он ведет себя нормально.

Вот код одной из частей, в которой происходит это поведение:

UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:@"You are in the right place." message:nil delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [locationAlert show];
        [locationAlert release];

Или, если хотите, с немного большим контекстом:

- (IBAction)locateMe {
NSLog(@"About to check location");
locMan = [[CLLocationManager alloc] init];
locMan.delegate = self;
locMan.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
locMan.distanceFilter = 1609; //1 mile
[locMan startUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation * )oldLocation {
if (newLocation.horizontalAccuracy >= 0) {

    CLLocation *airportLocation = [[[CLLocation alloc] initWithLatitude:51.500148 longitude:-0.204669] autorelease];
    CLLocationDistance delta = [airportLocation getDistanceFrom: newLocation];
    long miles = (delta * 0.000621371) + 0.5; //metres to rounded mile
    if (miles < 3) {
        UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:@"You are in the right place." message:nil delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [locationAlert show];
        [locationAlert release];
        [locMan stopUpdatingLocation];
    } else {
        UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:@"You are not in the right place." message:nil delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [locationAlert show];
        [locationAlert release];
        [locMan stopUpdatingLocation];

    }
}
}

- (void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:@"Error." message:error.code delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];

[locationAlert show];
[locMan release];
locMan = nil;
}

Есть идеи?Спасибо.

Редактировать---------

Другое место, где это происходит:

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString * errorString = [NSString stringWithFormat:@"Unable to download feed from web site (Error code %i )", [parseError code]];
NSLog(@"error parsing XML: %@", errorString);

UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:@"Error loading content" message:errorString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[errorAlert show];
}

Для контекста первый случай находится в AppDelegate, а второй — в контроллере представления для первого представления вкладки.Вторая проблема возникает каждый раз, когда XML перезагружается при отсутствии подключения к Интернету.Первое происходит только при первом вызове функции.

Редактировать-----

Если я перенесу предупреждение, оно сработает.К сожалению, это не то, чего я хочу!

- (IBAction)locateMe {

 UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:@"You are in the right place." message:nil delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[locationAlert show];
/*
NSLog(@"About to check location");
locMan = [[CLLocationManager alloc] init];
locMan.delegate = self;
locMan.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
locMan.distanceFilter = 1609; //1 mile
[locMan startUpdatingLocation];*/
}

Обновлять:

Я установил несколько записей NSLog и обнаружил, что, несмотря на добавление [locMan stopUpdatingLocation] функция DidUpdateToLocation запускалась несколько раз.

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

Любые идеи относительно того, почему [locMan stopUpdatingLocation] не работает, было бы оценено, но в то же время я просто переместил объявление locationAlert из функции (поэтому оно является глобальным), установил его в исходной функции «Найти меня» и использовал следующее при первом вызове:

[locationAlert show];
locationAlert = nil;

Таким образом, это работает идеально.

Это было полезно?

Решение

Я думаю, что НСАлерт исчезающий сам по себе является ключом к решению этой проблемы.

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

Для отладки я предлагаю:

(1) Поиск в вашем коде NSAlert. – dismissWithClickedButtonIndex:animated: и посмотрите, действительно ли вы каким-то образом программно отклоняете предупреждение.

(2) Я считаю (кто-нибудь меня перепроверит), что представление предупреждения добавляется в качестве подпредставления к любому базовому представлению, которое в данный момент отображается на экране.Возможно, по какой-то причине базовое представление исчезает, унося с собой представление оповещений.Если представление исчезает, а затем появляется снова достаточно быстро, это может быть неочевидно, когда предупреждение находится на переднем плане.(Редактировать:см. комментарий Эда Марти ниже.)

(3) Поскольку это происходит в двух отдельных частях приложения, сравните обе, чтобы найти общий элемент или структуру.Этот общий элемент может быть причиной.Странная проблема.

Редактировать01:Обновлено для получения дополнительной информации

Если locMan isan, она должна быть определена как свойство, и вы должны обращаться к ней каждый раз с помощьюself.locMan Получив к нему прямой доступ, вы потеряете автоматическое управление хранением.

Другие советы

Вы не выключаете диспетчер местоположения при первом показе оповещения.По мере того как местоположение уточняется устройством (т. е. точность увеличивается), ваш обратный вызов будет (потенциально) вызываться несколько раз.Вам следует использовать [locMan stopUpdatingLocation] после отображения предупреждения.

Я установил несколько записей NSLog и обнаружил, что, несмотря на добавление [locMan stopUpdatingLocation], функция DidUpdateToLocation запускалась несколько раз.

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

Любые идеи относительно того, почему [locMan stopUpdatingLocation] не работает, будут оценены по достоинству, но в то же время я просто переместил объявление locationAlert из функции (поэтому оно является глобальным), установил его в исходную функцию find me и использовал следующее при первом вызове:

[locationAlert show];
locationAlert = nil;

Таким образом, это работает идеально.

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

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if([string isEqualToString:@"OK"]) {
    NSLog(@"(Settings)Registration Successful");
    statusField.text = @"Registration successful!";
    [settingsActivity stopAnimating];
}
else {
    NSLog(@"(Settings)Registration Failure");
    [settingsActivity stopAnimating];

    UIAlertView * regFail = [[[UIAlertView alloc] initWithTitle:@"Registration Error!" message:@"Please check your email address and try again." delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil] autorelease];

    [regFail show];
}}

Чтобы исправить это поведение, я просто проверил возвращаемую строку, а не просто показывал предупреждение:

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if([string isEqualToString:@"OK"]) {
    NSLog(@"(Settings)Registration Successful");
    statusField.text = @"Registration successful!";
    [settingsActivity stopAnimating];
}
else if([string isEqualToString:@"Error"]) {
    NSLog(@"(Settings)Registration Failure");
    [settingsActivity stopAnimating];

    UIAlertView * regFail = [[[UIAlertView alloc] initWithTitle:@"Registration Error!" message:@"Please check your email address and try again." delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil] autorelease];

    [regFail show];
}

У меня также возникла та же проблема при работе над Location Manager.Здесь я проверил с помощью Nslog, но он выполняется несколько раз, наконец, я обнаружил, что создаю несколько объектов и использую Sharedinstance для того же ViewController, который содержит диспетчер местоположения, но я не освобождаю объект, поэтому в конкретном месте, сколько объектов, если мы создадим это много раз местоположение обнаруживается. Поэтому во время работы над LocationManger тщательно проверяйте обработку объектов, чтобы уменьшить количество проблем такого типа.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top