This is driving me crazy!!!
I'm getting a "Received memory warning. Level=1" whenever I attempt to show a UIImagePickerController with a sourceType = UIImagePickerControllerSourceTypeCamera.
Here is the code from my viewDidLoad where I set things up:
- (void)viewDidLoad {
[super viewDidLoad];
// Set card table green felt background
self.view.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed:@"green_felt_bg.jpg"]];
// Init UIImagePickerController
// Instantiate a UIImagePickerController for use throughout app and set delegate
self.playerImagePicker = [[UIImagePickerController alloc] init];
self.playerImagePicker.delegate = self;
self.playerImagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
And here is how I present it modally ..
- (IBAction) addPlayers: (id)sender{
[self presentModalViewController:self.playerImagePicker animated:YES];
}
The result ... UIImagePicker starts to show and then boom ... I get the memory warning ... EVERY TIME! Interestingly enough, if I switch to sourceType = UIImagePickerControllerSourceTypePhotoLibrary ... everything works fine.
What in the heck am I missing or doing wrong? All I want to do is show the camera, take and save a picture.
FYI - I'm testing on my 3GS device.
Thanks to anyone who can help :)
Now after I upgraded to 4.0 it happens to my app too - before in 3.1 there were no warnings.
Actually as you said before, there should be no issue. However, this causes the view that comes after it to load again and viewDidLoad is being called. This messes up my app, since I initialize the view in viewDidLoad - now it gets initialized all over again - even though it shouldn't.
Just as a comment, this might also happen to many other apps that rely on loading the view only once!
I'm getting the memory warning when opening a UIImagePickerController as well. I'm on 4.01 as well. But in addition, the UIImagePickerController is running the close shutter animation and stalling there, with the closed shutter on screen.
It seems like the UIImagePickerController's behavior on memory warnings is to close itself. I could dismiss the UIImagePickerController from the parent ViewController in the didReceiveMemoryWarning method, but that would make for a terrible user experience.
Has anyone seen this problem? Is there a way to handle the memory warning so that the UIImagePickerController doesn't shut itself down?
It did happen in my app Did I Do That on iOS 4.0 too. It was not consistent, but the most common cause was creating a
UIImagePickerController
instance and navigating to some large photo stored in one of the albums.Fixed by persisting state in the
didReceiveMemoryWarning
method, and loading from state in the viewDidLoad method. One caveat is to remember to clear the state-persisted file in the correct point for your application. For me it was leaving the relevant UIViewController under normal circumstances.It is not about how much memory your app has used, because it will probably happen even when you write a very simple app which have only one view with one button, clicking the button and then open camera. I have tested on iPhone 3GS, iPad 2 and iPod touch 3G. It only happened in iPhone 3GS. I found it will not happen anymore if you restart you device before you execute you app.
Another real solution is to comment the code,
[super didReceiveMemoryWarning]
, in your viewController.After lots of test on iPhone 3GS with iOS 4.3.2, I found the logic might like that: -> Open as much as app running on background -> Presenting a imagePicker of UIImagePickerController, clicking "Back" or "Save" from imagePicker -> ApplicationDelegate's method,
applicationDidReceiveMemoryWarning:(UIApplication *)application
, will be invoked -> Then ViewController's method,didReceiveMemoryWarning:
, will be invoked -> Then viewDidUnload -> Then viewDidLoadThen you could find some views have been released and the current view has been pointed to a unexpected one.
By default,
[super didReceiveMemoryWarning]
will run when ViewController'sdidReceiveMemoryWarning
method is invoked. Commenting it, andviewDidUnload:
andviewDidLoad:
methods will not be invoked. It means the mem warning has been totally ignored. That's what we expected.The
UIImagePickerControllerDelegate
is a memory hog because you are capturing high memory assets, be that an image or video. So from the start be sure to specify the medium capture settings, as a start point, reduce this if you don't need the quality:Then after capturing and using these assets. Remove any temp files from the applications temp folder. Could be an extra obsessive step but its a good habit:
With above it is clearing the file that was created by the delegate. In some instances if you are transcoding or creating you own assets delete the folder with that file. Note above I am removing the 'file://' part of the url string as the file manager doesn't like it:
Other things to consider are covered in the various documentation for what you are doing with that asset - transcoding, image size reduction and more. Beware that any transcoding using the
AVFoundation
will crash if theUIImagePickerViewController
is displaying.I have been struggling with the same problem for some days now. However, resetting my iPhone 4 (clearing out memory) solves the problem so it's not really an app problem.
It appears that a level 1 or 2 memory warning triggers the UIimgPickerController delegate to offload itself. The same happens in my app with the delegate of the delegate (yes it can). After the memory warning however, it will load the delegate (and it's delegate) again causing the viewDidLoad to execute any code that's in there.
I am not sure this happens only while using the UIimgPickerController because testing all that is very time consuming.
I could write some extra code to prevent the code in viewDidLoad en viewWillAppear from execuring while showing the UIimgPickerController but that's not classy, right?