Правильное использование UIImagePickerController для фотографирования с помощью камеры или выбора их из библиотеки iphone - PullRequest
2 голосов
/ 11 августа 2010

Что я хочу сделать, так это всегда использовать один и тот же экземпляр UIImagePickerController во всем моем приложении, так как я не хочу выделять и уничтожать мой сборщик каждый раз, когда пользователь делает снимок.Приложение использует средство выбора и UIImageView с именем pictureA, чтобы показать изображение, выбранное из альбома 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];
}

Приложение будет работать правильно, когда я сделаю первый снимок, но когда я пытаюсь сделать еще один снимок или выбрать другое изображение из моей библиотеки, оно выглядит точно так же, как в последний раз, когда я выбирал изображение (с изображением на всем экране инеактивное меню для выбора и отмены внизу).Мое приложение работает правильно только в том случае, если я удаляю контроллер из поля зрения и выделяю его каждый раз, когда пользователь делает снимок.Есть ли способ «очистить» или «перезапустить» сборщик, не отпуская его и не удаляя его из моего поля зрения?

Я также не уверен, смогу ли я один раз создать экземпляр UIImageView (pictureA), где я хранюИзображение, полученное с помощью imagePickerController и изменяющее его каждый раз, когда пользователь делает снимок или выбирает одно из альбома, я подозреваю, что неправильно уничтожать его и перераспределять его каждый раз, когда пользователь делает снимок.Любые предложения? Что-то я делаю неправильно в отношении управления памятью или использования UIImagePickerController и UIImageView?

спасибо!

1 Ответ

0 голосов
/ 10 февраля 2012

Я не думаю, что UIImagePickerControllers предназначены для повторного использования. В любом случае, они используют ТОННУ памяти (особенно камеры), поэтому вы не хотите хранить их дольше, чем нужно. Так что да, вы должны освободить средство выбора изображений, когда закончите с ним, и создать новое, когда вы хотите добавить другое изображение.

Вероятно, вы должны представлять свой сборщик изображений модально:

[self presentModalViewController:imagePickerController animated:YES];

Вам не нужно отпускать изображение. Просмотр изображения каждый раз, когда вы хотите изменить изображение. Просто измените свойство изображения.

pictureA.image = newImage;

Если вы хотите создать экземпляр представления изображения при первом его использовании, сделайте что-то вроде

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

pictureA.image = ...

Имейте в виду, что для вызова alloc требуется соответствующий вызов либо для освобождения, либо для автоматического выпуска. Когда вы выделили «pictureA» выше, его счетчик сохранения стал 1. вызывая «[self addSubview: pictureA];» увеличил количество сохраняемых файлов до 2. Когда вы вызываете «[pictureA removeFromSuperview];» в следующий раз количество сохранений было уменьшено до 1, и вы создали новый просмотр изображений. Поэтому каждый раз, когда вызывается imagePickerController: didFinishPickingMediaWithInfo: вы теряете память. Вместо этого сделайте

[pictureA removeFromSuperview];
[pictureA release];

когда вы удалите его из суперпредставления. Или, еще лучше, сделайте изображение свойством класса:

@property (nonatomic, retain) UIImageView *pictureA;

, который освободит старый imageView при назначении нового. Обязательно отпустите, когда назначите его:)

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

или

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

Я бы лично придерживался стиля автоматического выпуска, потому что вы всегда сможете сразу определить, правильно ли вы распределяете / удаляете.

Кроме того, вы всегда можете дважды проверить управление памятью, используя Product> Analyze в Xcode 4.

...