iOS 7 bug or my bug in UIAlertView
I have got the following stack trace while my app crashes on tapping "OK" on a UIAlertView. Is it my fault or a iOS7 bug? I don't know how to fix this.
OS Version: iOS 7.0 (11A465)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000000
Triggered by Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x39d50b36 objc_msgSend + 22
1 UIKit 0x3212e3da -[UIAlertView(Private) modalItem:shouldDismissForButtonAtIndex:] + 58
2 UIKit 0x31ed2036 -[_UIModalItemsCoordinator _notifyDelegateModalItem:tappedButtonAtIndex:] + 90
3 UIKit 0x31ed1f3e -[_UIModalItemAlertContentView tableView:didSelectRowAtIndexPath:] + 890
4 UIKit 0x31dd7326 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1074
5 UIKit 0x31e8a24e -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 210
6 UIKit 0x31d3a96e _applyBlockToCFArrayCopiedToStack + 314
7 UIKit 0x31cb246e _afterCACommitHandler + 426
8 CoreFoundation 0x2f5141d2 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 18
9 CoreFoundation 0x2f511b74 __CFRunLoopDoObservers + 280
10 CoreFoundation 0x2f511eb6 __CFRunLoopRun + 726
11 CoreFoundation 0x2f47cce2 CFRunLoopRunSpecific + 518
12 CoreFoundation 0x2f47cac6 CFRunLoopRunInMode + 102
13 GraphicsServices 0x3417727e GSEventRunModal + 134
14 UIKit 0x31d1ea3c UIApplicationMain + 1132
15 MyApp 0x000d8e5e 0xcb000 + 56926
16 libdyld.dylib 0x3a25dab4 start + 0
Alert view code
UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error"
message:[NSString stringWithFormat:@"Es ist ein Fehler aufgetreten: %@", [error localizedDescription]]
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[av show];
and I haven't defined a delegate method.
Solution 1:
Stupid me, I just have to set the alert view's delegate to nil
Solution 2:
Because the delegate of the UIAlertView
is an assign property in UIAlertView
. I think that it is Apple's fault. It should be a weak pointer in ARC. But it is an assign property so you need to set the any alert view's delegate to nil
before destroying the delegate (most of the time a controller class got popped or navigated back). Read the .h file for UIAlertView
about the delegate, you can find it is an assign property and someone commented after the declaration saying "//weak reference".
Solution 3:
The best way to avoid problem with UIAlertView while using delegation is to make instance of UIAlertView as iVar for delegate class. And after you should make delegate property of alertView as nil in dealloc of delegate class
@implementation YOUR_CLASS
{
UIAlertView *_alert;
}
- (void)dealloc
{
_alert.delegate = nil;
}
- (void)showAlertView
{
_alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}
The same approach is good enough for all old classes with assign-type delegates.