UIAlertView 每次调用都会弹出三次,而不是一次

发布于 2024-08-21 22:11:59 字数 3741 浏览 8 评论 0原文

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

这样它就可以完美工作。

I am getting odd behavior from an NSAlert in two different parts of my program. The behavior is:

  1. Alert appears and then spontaneously disappears.
  2. Alert reappears and then remains until dismissed by user i.e. normal behavior.
  3. Alert reappears again.

This behavior only occurs the first time the method that displays the alert is called. After that first time, it behaves normally.

Here is the code for the one of the parts in which the behavior occurs:

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

Or if you prefer, with a bit more context:

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

Any ideas? Thanks.

Edit---------

The other place this happens is:

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

For context the first case is in the AppDelegate and the second in the view controller for the 1st tab view. The second problem occurs every time the xml is reloaded when there is no internet connection. The first one only occurs the first time the function is called.

Edit-----

If I move the alert it works. Unfortunatly this is not where I want it!

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

Update:

I set some NSLog entries and discovered that despite the addition of [locMan stopUpdatingLocation] the didUpdateToLocation function was running multiple times.

I guess the spontaneous disappearance happens because the alert view is called again and the programme clears the first instance to make way for the second automatically.

Any ideas as to why [locMan stopUpdatingLocation] doesn't work would be appreciated but in the mean time I just moved the declaration of the locationAlert out of the function (so it is global), set it in the initial locate me function and use the following the first time it is called:

[locationAlert show];
locationAlert = nil;

That way it works perfectly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

暖心男生 2024-08-28 22:11:59

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

You're not turning off your location manager when you first show the alert. As the location is refined by the device (ie, the accuracy is increased), your callback will be (potentially) called multiple times. You should use [locMan stopUpdatingLocation] after your alert display.

吻泪 2024-08-28 22:11:59

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

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

关于为什么 [locMan stopUpdatingLocation] 不起作用的任何想法都将受到赞赏,但与此同时,我刚刚将 locationAlert 的声明移出函数(因此它是全局的),将其设置在初始的“定位我”函数中并使用第一次调用时如下:

[locationAlert show];
locationAlert = nil;

这样它就完美地工作了。

I set some NSLog entries and discovered that despite the addition of [locMan stopUpdatingLocation] the didUpdateToLocation function was running multiple times.

I guess the spontaneous disappearance happens because the alert view is called again and the programme clears the first instance to make way for the second automatically.

Any ideas as to why [locMan stopUpdatingLocation] doesn't work would be appreciated but in the mean time I just moved the declaration of the locationAlert out of the function (so it is global), set it in the initial locate me function and use the following the first time it is called:

[locationAlert show];
locationAlert = nil;

That way it works perfectly.

梦亿 2024-08-28 22:11:59

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

解释为什么警报会意外显示很简单,即它只是被意外调用。然而,以编程方式消除警报的情况并不常见。无论是什么原因导致它消失,很可能会再次触发显示。

为了调试,我建议:

(1)在代码中查找 NSAlert –dismissWithClickedButtonIndex:animated: 方法,看看您是否实际上以编程方式消除了警报。

(2) 我相信(有人对此进行了仔细检查)警报视图作为子视图添加到当前屏幕上的任何基本视图中。可能是基础视图由于某种原因消失了,并且警报视图也随之消失了。如果视图消失然后足够快地重新出现,则当​​警报位于最前面时,它可能不会很明显。 (编辑:请参阅下面 Ed Marty 的评论。)

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

Edit01:更新附加信息

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

I think the NSAlert disappearing on its own is the key to solving this.

It's simple to explain why an alert displays unexpectedly i.e. it's just been called unexpectedly. However, it's not so common to programmatically dismiss an alert. Whatever is causing it to disappear is most likely triggering the display again.

To debug I suggest:

(1) Looking in your code for the NSAlert – dismissWithClickedButtonIndex:animated: method and see if somehow you're actually dismissing the alert programmatically.

(2) I believe (someone double-check me on this) that an alert view is added as a subview to whichever base view is currently on screen. It might be that the base view is disappearing for some reason and taking the alert view with it. If the view disappears and then reappears rapidly enough, it might not be obvious when the alert is frontmost. (Edit: see Ed Marty's comment below.)

(3) Since this happens in two separate pieces of the app, compare both to find a common element or structure. That common element might be the cause.
An odd problem.

Edit01: Updated for additional info

If locMan isan instance variable, it should be defined as a property and you should access it every time withself.locMan By accessing it directly, you lose your automatic retention management.

若相惜即相离 2024-08-28 22:11:59

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

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

I encountered the same exact issue with the alert dialog appearing momentarily, reappearing, and finally appearing again after being dismissed. I was making a string comparison before deciding to show the alert view:

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

To correct this behavior I simply verified the returned string rather than just showing the alert:

- (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];
}
青衫儰鉨ミ守葔 2024-08-28 22:11:59

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

I also got the Same problem while working on Location Manager. Here i checked with Nslog but it is executing multiple times, finally i fount that i am creating multiple objects and using Sharedinstance for same ViewController that contains Location Manger but i am not releasing the object, so at perticular location how many objects if we create that many times the location detects.So while working on LocationManger check handling objects thoroughly to reduce these type of problems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文