I'm seeing a memory leak in iOS 8 in simulator when I do the following with UIActionSheet or UIAlertController. UIActionSheet uses UIAlertController in IOS 8 so the issues are related.
showCameraAction gets called when a button is pressed. I've removed all of the content from the delegate method and still get the leak in the case shown below. Am I using UIActionSheet in some way that I shouldn't? I would appreciate any help in resolving this issue. The same code has no leaks with IOS 7 (in the simulator).
-(IBAction)showCameraAction:(id)sender
{
UIActionSheet* actionSheet = [[UIActionSheet alloc] initWithTitle:@"Photo From:"
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:@"Phone", @"Flickr", nil];
[actionSheet showInView:[[UIApplication sharedApplication] keyWindow]];
//also tried just showInView: self.view
}
//empty
- (void)actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex {
}
Also tried with UIAlertController, with the same result:
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:@"Photo From:"
message:@""
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *phoneAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"Phone", @"Phone action")
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
NSLog(@"Phone action");
}];
UIAlertAction *flickrAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"Flickr", @"Flickr action")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
NSLog(@"Flickr action");
}];
[alertController addAction:phoneAction];
[alertController addAction:flickrAction];
[self presentViewController:alertController animated:YES completion:nil];
Screenshot with trace: https://www.dropbox.com/l/FmnTCd0PvVhuu16BVHZo7p
I would suggest to use "UIAlertController" in iOS8. And dismiss the alertController object from the presented controller, while firing any event by "UIAlertAction" block.
This is an iOS bug.
See Apple Bug Reporter issue 21005708, Memory leak in UIAlertController under ARC.
This is no answer, but more evidence for the leak, that exceeds a comment. May it help to find a solution or workaround. The leak seems to be device specific on iPad 3/Retina!
I have made some tests myself by overriding retain and release of the view-controller to show the leak in iOS 8.x
See also: https://devforums.apple.com/message/1099577#1099577
AGC is the view-controller. The correct retain count should be 2.
iPad Retina Simulator iOS 8.1 AND real iPad LEAK
// second run ... this time with LEAK by selecting an option 12:56:50.929 SimplySolitaire[27643:473670] >>> WILL actionSheet showInView: retain = 2 12:56:50.930 SimplySolitaire[27643:473670] AGC retain == 3 12:56:50.950 SimplySolitaire[27643:473670] AGC retain == 4 12:56:50.951 SimplySolitaire[27643:473670] AGC retain == 5 12:56:50.951 SimplySolitaire[27643:473670] AGC retain == 6 12:56:50.951 SimplySolitaire[27643:473670] <<< DID actionSheet showInView: retain = 6 12:56:50.998 SimplySolitaire[27643:473670] AGC release = 5 12:56:51.042 SimplySolitaire[27643:473670] AGC release = 4 12:56:51.042 SimplySolitaire[27643:473670] AGC release = 3 // USER dismisses the action sheet with tapping a button (delegate is nil) 12:56:53.257 SimplySolitaire[27643:473670] AGC retain == 4 12:56:53.257 SimplySolitaire[27643:473670] AGC retain == 5 12:56:53.258 SimplySolitaire[27643:473670] AGC retain == 6 12:56:53.258 SimplySolitaire[27643:473670] AGC retain == 7 12:56:53.258 SimplySolitaire[27643:473670] AGC release = 6 12:56:53.259 SimplySolitaire[27643:473670] AGC release = 5 12:56:53.612 SimplySolitaire[27643:473670] AGC release = 4 12:56:53.612 SimplySolitaire[27643:473670] AGC release = 3 // <<<<<<<<<< LEAK should be 2 // the last release is missing, but only iOS system code has executed.
iPad Retina Simulator iOS 8.1 AND real iPad, dismiss without LEAK
12:54:54.757 SimplySolitaire[27643:473670] >>> WILL actionSheet showInView: retain = 2 12:54:54.758 SimplySolitaire[27643:473670] AGC retain == 3 12:54:54.798 SimplySolitaire[27643:473670] AGC retain == 4 12:54:54.798 SimplySolitaire[27643:473670] AGC retain == 5 12:54:54.798 SimplySolitaire[27643:473670] AGC retain == 6 12:54:54.798 SimplySolitaire[27643:473670] <<< DID actionSheet showInView: retain = 6 12:54:54.845 SimplySolitaire[27643:473670] AGC release = 5 12:54:54.891 SimplySolitaire[27643:473670] AGC release = 4 12:54:54.891 SimplySolitaire[27643:473670] AGC release = 3 // NOW ... dismiss the action sheet without selection (delegate is nil) 12:55:05.643 SimplySolitaire[27643:473670] AGC retain == 4 12:55:05.644 SimplySolitaire[27643:473670] AGC retain == 5 12:55:05.644 SimplySolitaire[27643:473670] AGC retain == 6 12:55:05.644 SimplySolitaire[27643:473670] AGC retain == 7 12:55:05.645 SimplySolitaire[27643:473670] AGC release = 6 12:55:05.645 SimplySolitaire[27643:473670] AGC release = 5 12:55:05.996 SimplySolitaire[27643:473670] AGC release = 4 12:55:05.997 SimplySolitaire[27643:473670] AGC release = 3 12:55:05.997 SimplySolitaire[27643:473670] AGC release = 2 // this is a correct retain of 2
I would suggest switching to UIAlertController. UIActionSheet is deprecated in iOS 8, so you might try giving it a shot and see if there's still the leak