What I want to do is to always use the same instance of UIImagePickerController in my whole app, since i don't want to alloc and destroy my picker every time the user takes a picture. The app uses a picker and an UIImageView named pictureA to show the picture choossen from the iPhone album or taken with the camera.
At start I allock my picker view controller like this:
imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
[self addSubview:imagePickerController.view];
When I take picture from the picker and place it in my UIImageView:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMe开发者_运维技巧diaWithInfo:(NSDictionary *)info{
// newImage is a UIImage do not try to use a UIImageView
UIImage *newImage = [info objectForKey:@"UIImagePickerControllerEditedImage"];
[pictureA removeFromSuperview];
CGRect myImageRect = CGRectMake(30.0f, 38.0f, 125.0f, 125.0f);
pictureA = [[UIImageView alloc] initWithFrame:myImageRect];
pictureA.contentMode= UIViewContentModeScaleAspectFit;
[pictureA setImage:newImage];
pictureA.opaque = YES;
[self addSubview:pictureA];
[newImage release];
[picker dismissModalViewControllerAnimated:YES];
[picker.view setHidden:YES];
}
When chooses a picture from the iphone's library:
- (void) chooseImageFromLibrary {
[imagePickerController.view setHidden:NO];
imagePickerController.allowsEditing = YES;
[imagePickerController viewWillAppear:YES];
[imagePickerController viewDidAppear:YES];
}
Cancel:
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
[picker.view setHidden:YES];
}
- (void) takePicture {
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
[(MainScene*)[melonGame actualScene] setCameraDissabled:YES];
return;
}
[imagePickerController.view setHidden:NO];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.allowsEditing = YES;
[imagePickerController takePicture];
[imagePickerController viewWillAppear:YES];
[imagePickerController viewDidAppear:YES];
}
The app will work properly when i take the first picture, but when i try to take another picture or choose another picture from my library it looks exactly as the last time i selected a picture ( with the picture in all the screen and an inactive menu to choose and cancel at the bottom). My app only works correctly if i remove the controller from my view and alloc it every time the user takes a picture. Is there any way to "clean" or "restart" the picker without releasing it and removing it from my view ?
I'm also not sure if i can instance once the UIImageView ( pictureA) where I store the image taken by the imagePickerController and modify it every time the user takes a picture or chooses one from the album, i suspect that it's incorrect to destroy it and realloc it every time the user takes a picture. Any suggestions ?, any thing i'm doing wrong regarding memory management or the use of the UIImagePickerController and the UIImageView ?
thanks !
I don't think UIImagePickerControllers are meant to be re-used. Either way, they use a TON of memory (especially the camera), so you don't want to keep them around any longer than you have to. So yes, you should release the image picker when you're done with it, and create a new one when you want to add another image.
You should probably be presenting your imagepicker modally:
[self presentModalViewController:imagePickerController animated:YES];
You don't need to release your pictureA image view every time you want to change the image. Just change the image property.
pictureA.image = newImage;
If you want to instantiate the image view the first time you use it, do something like
if (!pictureA) {
pictureA = [[UIImageView alloc] initWithFrame:aFrame];
}
pictureA.image = ...
Keep in mind that a call to alloc needs a matching call to either release or autorelease. When you allocated "pictureA" above, its retain count became 1. calling "[self addSubview:pictureA];" increased its retain count to 2. When you called "[pictureA removeFromSuperview];" next time around, the retain count was decreased to 1, and you created a new imageview. So every time imagePickerController:didFinishPickingMediaWithInfo: is called, you will leak memory. Instead, do
[pictureA removeFromSuperview];
[pictureA release];
when you remove it from superview. Or, better yet, make picture a property of the class:
@property (nonatomic, retain) UIImageView *pictureA;
which will release the old imageView when you assign a new one. Just make sure to release when you assign it :)
self.pictureA = [[[UIImageView alloc] init] autorelease];
or
UIImageView *imageView = [[UIImageView alloc] init];
self.pictureA = imageView;
[imageView release];
I would personally stick with the autorelease style because you'll always be able to tell at a glance if you're allocing/deallocing properly.
Also, you can always double-check your memory management using Product>Analyze in Xcode 4.
精彩评论