UIAlertView выскакивает три раза за вызов вместо одного раза
Я получаю странное поведение от NSAlert в двух разных частях моей программы. Поведение это:
- Оповещение появляется, а затем самопроизвольно исчезает.
- Оповещение появляется снова, а затем остается до тех пор, пока пользователь не отклонит его, т.е. нормальное поведение.
- Оповещение появляется снова.
Это происходит только при первом вызове метода, который отображает предупреждение. После этого в первый раз он ведет себя нормально.
Вот код для одной из частей, в которой происходит поведение:
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 из функции (поэтому оно является глобальным), установил его в исходной функции locate me и использовал следующий раз при первом вызове:
[locationAlert show];
locationAlert = nil;
Таким образом, это работает отлично.
5 ответов
Я думаю, что исчезновение NSAlert само по себе является ключом к решению этой проблемы.
Просто объяснить, почему предупреждение отображается неожиданно, т. Е. Оно было вызвано неожиданно. Тем не менее, не так часто программно отключить предупреждение. Что бы ни вызывало его исчезновение, скорее всего, снова запускается дисплей.
Для отладки я предлагаю:
(1) Поиск в вашем коде для NSAlert – dismissWithClickedButtonIndex:animated:
метод и посмотреть, если вы как-то на самом деле отклонить предупреждение программно.
(2) Я полагаю (кто-то дважды проверяет меня в этом), что представление предупреждений добавляется в качестве подпредставления к любому основному представлению, которое в данный момент находится на экране. Возможно, по какой-то причине базовое представление исчезает, и оно принимает представление с предупреждением. Если представление исчезает, а затем появляется достаточно быстро, это может быть неочевидно, когда предупреждение находится на первом плане. (Изменить: см. Комментарий Эд Марти ниже.)
(3) Поскольку это происходит в двух отдельных частях приложения, сравните обе, чтобы найти общий элемент или структуру. Этот общий элемент может быть причиной. Странная проблема.
Edit01: Обновлено для дополнительной информации
Если locMan
переменная экземпляра, она должна быть определена как свойство, и вы должны обращаться к ней каждый разself.locMan
Получая прямой доступ к нему, вы теряете автоматическое управление хранением.
Вы не выключаете свой менеджер местоположения, когда впервые показываете предупреждение. Поскольку местоположение уточняется устройством (т. Е. Точность увеличивается), ваш обратный вызов будет (потенциально) вызываться несколько раз. Вы должны использовать [locMan stopUpdatingLocation] после отображения вашего предупреждения.
Я установил несколько записей NSLog и обнаружил, что, несмотря на добавление [locMan stopUpdatingLocation], функция didUpdateToLocation выполнялась несколько раз.
Я предполагаю, что самопроизвольное исчезновение происходит, потому что представление предупреждения вызывается снова, и программа очищает первый экземпляр, чтобы освободить место для второго автоматически.
Любые идеи относительно того, почему [locMan stopUpdatingLocation] не работает, будут оценены, но в то же время я просто переместил объявление locationAlert из функции (поэтому оно является глобальным), установите его в исходной функции locate 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, который содержит Location Manger, но я не освобождаю объект, так что в расположении в перкулярной области, сколько объектов, если мы создаем это много раз обнаруживает местоположение. Так что во время работы над LocationManger тщательно проверяйте объекты, чтобы избежать подобных проблем.