2

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

这样它就可以完美地工作。

4

5 回答 5

2

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

于 2010-02-16T13:53:57.433 回答
1

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

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

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

[locationAlert show];
locationAlert = nil;

这样它就可以完美地工作。

于 2010-02-16T19:13:26.257 回答
0

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

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

调试我建议:

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

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

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

Edit01:更新了更多信息

如果locMan是实例变量,则应将其定义为属性,并且每次都应使用self.locMan直接访问它来访问它,您将失去自动保留管理。

于 2010-02-16T14:21:51.443 回答
0

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

- (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];
}
于 2011-07-08T17:00:19.420 回答
0

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

于 2013-10-03T17:07:23.490 回答