Fixed a crash when more than one alert view is displayed at a time #6

Merged
merged 1 commit into from Jun 15, 2012

2 participants

@vytis

Currently the alert view does the job (run the block and release itself) in the - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex delegate method. This method also gets called when more than one alert view is shown. The crash can easily be reproduced using the following code snippet:

UIAlertView *one = [[[UIAlertView alloc] initWithTitle:@"one" message:@"one" cancelButtonItem:[RIButtonItem itemWithLabel:@"dismiss"] otherButtonItems: nil] autorelease];
UIAlertView *two = [[[UIAlertView alloc] initWithTitle:@"two" message:@"two" cancelButtonItem:[RIButtonItem itemWithLabel:@"dismiss"] otherButtonItems: nil] autorelease];
[one show];
[two show];

The crash happens when the second alert view is dismissed. To fix it the delegate method was changed to - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

@jivadevoe
Owner

Interesting bug... I'll have to think about this one. Does changing the code in this way still result in appropriate behavior? Meaning, do the actions for the correct alert view get called? I would think, if this bug is occurring, it would not. Meaning, simply changing the delegate method shouldn't fix the real problem.

@vytis

Yes, everything works as expected. The problem was that this particular delegate method also gets called when UIAlertView is hidden by another UIAlertView. I think this is the intended behavior as the documentation says:

This method is invoked after the animation ends and the view is hidden.
@jivadevoe
Owner

I hate to ask this, since I know this PR has been sitting here for like 9 months... but I just merged in some changes that add a dismissal block. I'm not sure that this fits with that, since the dismissal block may be called even if a button isn't tapped. Can you review this patch and tell me if it would still be viable based on the new functionality?

Again, my apologies for the long processing time on this.

@vytis

I saw that the dismissal block is only added to UIAlertSheet, but not UIAlertView. Are you adding it to the latter as well? This PR is only relevant to UIAlertView...

The crash seems to be gone now, but the action() is still getting called when alert views are stacked together. However I can only reproduce it with iOS 4.3, because 5.1 works as expected. You can try for yourself with this expanded example:

RIButtonItem *oneCancel = [RIButtonItem itemWithLabel:@"One"];
oneCancel.action = ^{NSLog(@"One!");};

RIButtonItem *twoCancel = [RIButtonItem itemWithLabel:@"Two"];
twoCancel.action = ^{NSLog(@"Two!");};

UIAlertView *one = [[[UIAlertView alloc] initWithTitle:@"one" message:@"one" cancelButtonItem:oneCancel otherButtonItems: nil] autorelease];
UIAlertView *two = [[[UIAlertView alloc] initWithTitle:@"two" message:@"two" cancelButtonItem:twoCancel otherButtonItems: nil] autorelease];
[one show];
[two show];

After dismissing both alert views on iOS 5.1 the console output is:

2012-05-28 13:41:41.545 test2[5417:f803] Two!
2012-05-28 13:41:42.558 test2[5417:f803] One!

while on iOS 4.3:

2012-05-28 13:46:11.632 test2[5473:b903] One!
2012-05-28 13:46:13.356 test2[5473:b903] Two!

"One!" is printer when the second alert pops up, but isn't printed when the actual button is pressed, because on the second call to alertView:didDismissWithButtonIndex: buttonsArray is nil.

So in short, the dismissal block (if implemented the same way as in UIAlertSheet) will get called even if no buttons are tapped, but only on iOS < 5.1 (possibly <5.0 but I haven't tried).

@jivadevoe jivadevoe merged commit 6753178 into jivadevoe:master Jun 15, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment