【问题标题】:UIAlertView Pops Up Three Times per Call Instead of Just OnceUIAlertView 每次调用都会弹出 3 次而不是一次
【发布时间】:2011-01-17 09:55:51
【问题描述】:

在我的程序的两个不同部分中,我从 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;

这样就完美了。

【问题讨论】:

    标签: iphone iphone-sdk-3.0 nsalert


    【解决方案1】:

    首次显示提醒时,您并没有关闭位置管理器。随着设备对位置进行优化(即准确性提高),您的回调将(可能)被多次调用。您应该在警报显示后使用 [locMan stopUpdatingLocation]。

    【讨论】:

    • 没有骰子。我在 [locationAlert release] 之​​后直接将其放入,并且行为没有改变。
    • 我的应用程序的非核心定位相关部分也存在问题。如果无法下载在线组件,则错误消息会闪烁相同的编号。次。
    • 我认为这可以解释为什么警报显示多次但不能解释为什么它会自发消失。
    • Nik1777 -- 在评论中发布您添加的代码,我将编辑您的问题以反映更改。 (时间允许)
    • 谢谢。我已经编辑了问题以包括更改(stopUpdatingLocation)和发生这种情况的其他地方。对于上下文,位置警报位于 AppDelegate 中,而 XML 位于第一个选项卡的视图控制器中。
    【解决方案2】:

    我设置了一些 NSLog 条目,发现尽管添加了 [locMan stopUpdatingLocation],但 didUpdateToLocation 函数还是运行了多次。

    我猜想自然消失是因为再次调用警报视图并且程序清除了第一个实例以自动为第二个实例让路。

    任何关于为什么 [locMan stopUpdatingLocation] 不起作用的想法将不胜感激,但同时我只是将 locationAlert 的声明移出函数(因此它是全局的),将其设置在初始位置我函数并在第一次调用时使用以下内容:

    [locationAlert show];
    locationAlert = nil;
    

    这样就完美了。

    【讨论】:

      【解决方案3】:

      我认为 NSAlert消失是解决这个问题的关键。

      很容易解释为什么警报会意外显示,即它只是被意外调用。但是,以编程方式关闭警报并不常见。导致它消失的原因很可能会再次触发显示。

      我建议调试:

      (1) 查看 NSAlert – dismissWithClickedButtonIndex:animated: 方法的代码,看看您是否真的以编程方式解除了警报。

      (2) 我相信(有人对此进行了仔细检查)警报视图作为子视图添加到当前屏幕上的任何基本视图。可能是由于某种原因,基本视图正在消失并带有警报视图。如果视图消失然后又快速地重新出现,那么当警报位于最前面时可能并不明显。 (编辑:见下面 Ed Marty 的评论。)

      (3) 由于这发生在应用程序的两个单独部分中,因此请比较两者以找到共同的元素或结构。这个共同因素可能是原因。 一个奇怪的问题。

      Edit01:更新了更多信息

      如果locMan是一个实例变量,它应该被定义为一个属性,你应该每次都用self.locMan访问它,如果直接访问它,你将失去你的自动保留管理。

      【讨论】:

      • 谢谢。 1. 我不记得在任何地方都使用过dismissWithClickedButtonIndex:animated 并且搜索代码目录没有返回任何内容。 2.我不知道如何检查这个。 3. 我找不到一个共同的奇怪之处,但我已经编辑了帖子以包含这两个代码,所以也许你可以看到一些东西。再次感谢。
      • 谢谢。当我为模拟器编译时,我遇到了一个我不明白的错误。当我为设备编译时它没有抱怨,所以我忽略了它。
      • 嘿,那个人以前咬过我。您应该进入项目设置并设置“将警告视为错误”,以便您必须停止并修复所有警告。警告只是一个不会终止构建的错误。所有警告最终都会导致问题,因此请随时修复它们。
      • 至于(2),这是不正确的。显示警报视图时,它会显示在位于主窗口顶部的自己的窗口中。
      • @Ed Marty - 感谢您的仔细检查。
      【解决方案4】:

      我遇到了同样的问题,警告对话框会暂时出现,再次出现,最后在被关闭后再次出现。在决定显示警报视图之前,我正在进行字符串比较:

      - (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];
      }
      

      【讨论】:

        【解决方案5】:

        我在使用位置管理器时也遇到了同样的问题。在这里,我检查了 Nslog,但它执行了多次,最后我发现我正在创建多个对象并为包含 Location Manger 的同一个 ViewController 使用 Sharedinstance 但我没有释放该对象,所以在特定位置,如果我们创建了多少个对象位置检测到很多次。因此,在使用 LocationManger 时,请彻底检查处理对象以减少此类问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-09-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多