正确使用UIImagePickerController既可以用相机拍照,也可以从iphone库中选择

时间:2010-08-11 18:19:37

标签: iphone uiimageview uiimagepickercontroller

我想做的是在我的整个应用程序中始终使用相同的UIImagePickerController实例,因为每次用户拍照时我都不想分配和销毁我的选择器。该应用程序使用一个选择器和一个名为pictureA的UIImageView来显示iPhone相册中的图片选择或用相机拍摄。

一开始我就像这样选择我的选择器视图控制器:

    imagePickerController = [[UIImagePickerController alloc] init];
    imagePickerController.delegate = self;
    [self addSubview:imagePickerController.view];

当我从选择器拍照并将其放入我的UIImageView时:

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(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];

    }

从iphone库中选择图片时:

- (void) chooseImageFromLibrary {
    [imagePickerController.view setHidden:NO];
        imagePickerController.allowsEditing = YES;
    [imagePickerController viewWillAppear:YES];
    [imagePickerController viewDidAppear:YES];
}

取消:

- (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];
}

当我拍摄第一张照片时,该应用程序将正常工作,但当我尝试拍摄另一张照片或从我的库中选择另一张照片时,它看起来与我最后一次选择照片完全相同(所有屏幕中的照片都是一个不活动的菜单,在底部选择和取消)。如果我从我的视图中删除控制器并在每次用户拍照时分配它,我的应用程序才能正常工作。有没有办法“清理”或“重新启动”选择器而不释放它并将其从我的视图中移除?

我也不确定我是否可以在我存储imagePickerController拍摄的图像的UIImageView(pictureA)中实例,并在每次用户拍照或从相册中选择一张时修改它,我怀疑它是不正确的每次用户拍照时销毁它并重新分配它。有什么建议吗?,关于内存管理或使用UIImagePickerController和UIImageView,我做错了什么?

谢谢!

1 个答案:

答案 0 :(得分:0)

我认为UIImagePickerControllers不会被重复使用。无论哪种方式,他们都使用TON内存(特别是相机),所以你不想让它们比你需要更长时间。所以,是的,您应该在完成后释放图像选择器,并在想要添加另一个图像时创建一个新的图像选择器。

你可能应该以模态方式呈现你的imagepicker:

[self presentModalViewController:imagePickerController animated:YES];

每次要更改图像时,无需释放pictureA图像视图。只需更改图像属性即可。

pictureA.image = newImage;

如果您想在第一次使用时实例化图像视图,请执行类似

的操作
if (!pictureA) {
    pictureA = [[UIImageView alloc] initWithFrame:aFrame];
}

pictureA.image = ...

请记住,对alloc的调用需要匹配调用release或autorelease。当您在上面分配“pictureA”时,其保留计数变为1.调用“[self addSubview:pictureA];”将保留计数增加到2.当你调用“[pictureA removeFromSuperview];”时下次,保留计数减少到1,您创建了一个新的imageview。所以每次调用imagePickerController:didFinishPickingMediaWithInfo:时,都会泄漏内存。相反,做

[pictureA removeFromSuperview];
[pictureA release];

从superview中删除它时。或者,更好的是,将图片作为该类的属性:

@property (nonatomic, retain) UIImageView *pictureA;

将在您指定新的imageView时释放旧的imageView。只需确保在分配时释放:)

self.pictureA = [[[UIImageView alloc] init] autorelease];

UIImageView *imageView = [[UIImageView alloc] init];
self.pictureA = imageView;
[imageView release];

我个人会坚持使用autorelease样式,因为你总是能够一眼就知道你是否正确分配/解除分配。

此外,您始终可以使用产品>在Xcode 4中进行分析来仔细检查内存管理。