UIImagePickerController Low Memory Crash at iOS 7 on iPad Mini
=====================================================================
In this article, we’ll explore a common issue that occurs when using UIImagePickerController
in iOS 7 on the iPad Mini: low memory crashes. We’ll dive into the code and explain what’s happening behind the scenes to help you troubleshoot and prevent similar issues.
Introduction to UIImagePickerController
UIImagePickerController
is a built-in Apple class that allows users to take photos or select images from their device’s gallery. When you create an instance of UIImagePickerController
, you can configure it with various settings, such as camera source type, image capture mode, and more.
The Issue: Low Memory Crash on iOS 7 iPad Mini
The problem lies in the way Apple handles memory management for UIImagePickerController
instances on older devices like the iPad Mini running iOS 7. When you allocate an instance of UIImagePickerController
, it retains a strong reference to the view controller that created it, even after the view controller is deallocated.
This can lead to a situation where the UIImagePickerController
instance remains in memory, consuming system resources, and eventually triggering a low memory warning or crash.
Code Review: The Problematic Code
Let’s examine the code snippet provided by the original poster:
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
UIImagePickerController *imagePickerController;
if ([UIUtilityClass isCurrentVersionIsIOS7OrGreater]) {
imagePickerController = [[UIImagePickerController alloc] init];
[imagePickerController setDelegate:self];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeImage,nil];
imagePickerController.allowsEditing=NO;
CGFloat scaleFactor=1.3f;
switch ([UIApplication sharedApplication].statusBarOrientation) {
case UIInterfaceOrientationLandscapeLeft:
imagePickerController.cameraViewTransform = CGAffineTransformScale(CGAffineTransformMakeRotation(M_PI * 90 / 180.0), scaleFactor, scaleFactor);
break;
case UIInterfaceOrientationLandscapeRight:
imagePickerController.cameraViewTransform = CGAffineTransformScale(CGAffineTransformMakeRotation(M_PI * -90 / 180.0), scaleFactor, scaleFactor);
break;
case UIInterfaceOrientationPortraitUpsideDown:
imagePickerController.cameraViewTransform = CGAffineTransformMakeRotation(M_PI * 180 / 180.0);
break;
default:
break;
}
}
else
{
imagePickerController = [[NonRotatingUIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeImage,nil];
imagePickerController.allowsEditing = YES;
}
popoverController = [[UIPopoverController alloc] initWithContentViewController:imagePickerController];
popoverController.delegate=self;
[popoverController presentPopoverFromRect:CGRectMake(626,142,120,135) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
[imagePickerController release];
newMedia = YES;
}
The problematic line is the release
call on the imagePickerController
instance. In ARC (Automatic Reference Counting), this line is unnecessary and can even cause issues.
The Solution: Remove the Release Call
In ARC-enabled projects, you don’t need to explicitly release objects that are managed by the compiler. The imagePickerController
instance will be automatically released when it goes out of scope.
To fix the issue, simply remove the release
call:
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
UIImagePickerController *imagePickerController;
if ([UIUtilityClass isCurrentVersionIsIOS7OrGreater]) {
imagePickerController = [[UIImagePickerController alloc] init];
[imagePickerController setDelegate:self];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeImage,nil];
imagePickerController.allowsEditing=NO;
CGFloat scaleFactor=1.3f;
switch ([UIApplication sharedApplication].statusBarOrientation) {
case UIInterfaceOrientationLandscapeLeft:
imagePickerController.cameraViewTransform = CGAffineTransformScale(CGAffineTransformMakeRotation(M_PI * 90 / 180.0), scaleFactor, scaleFactor);
break;
case UIInterfaceOrientationLandscapeRight:
imagePickerController.cameraViewTransform = CGAffineTransformScale(CGAffineTransformMakeRotation(M_PI * -90 / 180.0), scaleFactor, scaleFactor);
break;
case UIInterfaceOrientationPortraitUpsideDown:
imagePickerController.cameraViewTransform = CGAffineTransformMakeRotation(M_PI * 180 / 180.0);
break;
default:
break;
}
}
else
{
imagePickerController = [[NonRotatingUIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeImage,nil];
imagePickerController.allowsEditing = YES;
}
popoverController = [[UIPopoverController alloc] initWithContentViewController:imagePickerController];
popoverController.delegate=self;
[popoverController presentPopoverFromRect:CGRectMake(626,142,120,135) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
newMedia = YES;
}
By removing the release
call, you ensure that the imagePickerController
instance is properly released when it’s no longer needed, preventing low memory crashes and other issues.
Conclusion
In this article, we explored a common issue with UIImagePickerController
on iOS 7 devices: low memory crashes. We examined the problematic code snippet provided by the original poster and discovered that the issue was caused by an unnecessary release
call in ARC-enabled projects.
By removing the release
call, we fixed the issue and ensured proper memory management for the imagePickerController
instance. This fix is essential when working with UIImagePickerController
on older devices like the iPad Mini running iOS 7.
Last modified on 2024-05-04