Se bloquea después de seleccionar imágenes de UIImagePickerController (¿Relacionado con la pérdida de memoria?)

He estado tratando de minimizar mi huella de memoria conUIImagePickerController, pero estoy empezando a pensar que los problemas de memoria que tengo son el resultado de una gestión deficiente de la memoria, en lugar de una forma particular de manejar elUIImagePickerController objeto.

Mi flujo de trabajo es este: se hace clic en el botón "Editar imagen", que presenta unUIActionSheet. Esta hoja de acción le permite eliminar, tomar una foto, elegir de la biblioteca o cancelar. Si selecciona Elegir de la biblioteca o Tomar foto, Ialloc una instancia deUIImagePickerController y presentarlo, seguido de un lanzamiento deUIImagePickerController:

-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (actionSheet.tag != 999) {
        UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
        imagePicker.delegate = self;

        BOOL pickImage = nil;

        if (actionSheet.tag == iPhoneWithDelete) {
            switch (buttonIndex) {
                case 0:
                    object.objectImage = nil;
                    pickImage = NO;
                    break;
                case 1:
                    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
                    pickImage = YES;
                    break;
                case 2:
                    imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
                    pickImage = YES;
                    break;
                default:
                    pickImage = NO;
                    break;
            }
        } else if (actionSheet.tag == iPhoneNoDelete) {
            switch (buttonIndex) {
                case 0:
                    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
                    pickImage = YES;
                    break;
                case 1:
                    imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
                    pickImage = YES;
                    break;
                default:
                    pickImage = NO;
                    break;
            }       
        } else if (actionSheet.tag == iPodWithDelete) {
            switch (buttonIndex) {
                case 0:
                    object.objectImage = nil;
                    pickImage = NO;
                    break;
                case 1:
                    imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
                    pickImage = YES;
                    break;
                default:
                    pickImage = NO;
                    break;
            }
        } else if (actionSheet.tag == iPodNoDelete) {
            switch (buttonIndex) {
                case 0:
                    imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
                    pickImage = YES;
                    break;
                default:
                    pickImage = NO;
                    break;
            }
        }

        if (pickImage) {
            imagePicker.allowsEditing = YES;
            [self presentModalViewController:imagePicker animated:YES];
        } else {
            [self setupImageButton];
            [self setupChooseImageButton];
        }
        [imagePicker release];
    }
}

Una vez que recibo una selección de laUIImagePickerController, Guardo 2 imágenes, una versión redimensionada de la imagen editada para usar para una miniatura, y una versión de 800x600 de la imagen original sin editar en un atributo de relación (Transformacional, usando las mismas transformaciones de UIImage a PNG que se encuentran en el código de demostración de Recetas) para uso de visualización: (los métodos de cambio de tamaño se basan en el que se muestra enesta publicación SO.)

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{

    [self dismissModalViewControllerAnimated:YES];

    NSManagedObject *oldImage = object.imageFull;
    if (oldImage != nil)
    {
        [object.managedObjectContext deleteObject:oldImage];
    }

    NSManagedObject *image = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:object.managedObjectContext];
    object.imageFull = image;

    UIImage *rawImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];

    CGSize size = CGSizeMake(800, 600);

    UIImage *fullImage = [UIImageManipulator scaleImage:rawImage toSize:size];

    [image setValue:fullImage forKey:@"imageFull"];

    UIImage *processedImage = [UIImageManipulator scaleImage:[info objectForKey:@"UIImagePickerControllerEditedImage"] toSize:CGSizeMake(75, 75)];
    object.objectImage = processedImage;
    [self setupImageButton];
    [self setupChooseImageButton];

    rawImage = nil;
    fullImage = nil;
    processedImage = nil;
}

Cuando paso porviewDidUnload Estoy configurandoself.object = nily[object release] durantedealloc, pero sigo recibiendo advertencias de memoria después de aproximadamente 10 cambios de imagen, con un bloqueo de alrededor de 20. Esto me lleva a creer que no estoy sacando esa imagen completa de la memoria de la manera correcta. ¿Que me estoy perdiendo aqui?

Y en una segunda nota, ¿la fuente de la cámara usa significativamente más memoria que la fuente de los álbumes de fotos? Tiendo a tener más bloqueos cuando uso la cámara.

--EDITAR--

Comenzando una recompensa poralguna información sobre lo que puedo estar manejando mal. Actualizaré esta publicación con cualquier respuesta a cualquier cosa que no haya sido clara. Justo al final de mi ingenio sobre esto.

--EDIT 2--

Se modificó el código para tener en cuenta las sugerencias de chrissr y se implementóGCD para mejorar la usabilidad. ¿Es esto tan eficiente como se vuelve este proceso? Todavía recibo advertencias de memoria y un bloqueo de alrededor de 20 imágenes. Estoy seguro de que la combinación de hacer caroUIImage cambio de tamaño y usoUIImagePickerController está asesinando la CPU, pero no puedo imaginar que cada aplicación esté lidiando con la incertidumbre en torno aUIImagePickerController. Mi huella de memoria es de alrededor de 2 megas. He estado operando bajo el supuesto de que eso era un montón de gastos generales. ¿Debo reducir aún más esa huella?

Aquí está el código modificado:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{

    [self dismissModalViewControllerAnimated:YES];

    if (object.imagePath != nil) {
        [self deleteImages];
    }
    dispatch_queue_t image_queue;
    image_queue = dispatch_queue_create("com.gordonfontenot.app", NULL);

    dispatch_async(image_queue, ^{

        NSDate *now = [NSDate date];

        NSDateFormatter *f = [[NSDateFormatter alloc] init];
        [f setDateFormat:@"yyyyMMDDHHmmss"];

        NSString *imageName = [NSString stringWithFormat:@"Image-%@-%i", [f stringFromDate:now], arc4random() % 100];
        NSString *thumbName = [NSString stringWithFormat:@"%@-thumb", imageName];

        [f release];

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];

        NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:imageName];
        NSString *thumbPath = [documentsDirectory stringByAppendingPathComponent:thumbName];

        NSData *thumbImageData = UIImagePNGRepresentation([UIImageManipulator scaleImage:[info objectForKey:@"UIImagePickerControllerEditedImage"] toSize:CGSizeMake(120, 120)]);
        [thumbImageData writeToFile:thumbPath atomically:NO];
        dispatch_async(dispatch_get_main_queue(), ^{
            object.thumbPath = thumbPath;
            [self setupImageButton];
            imageButton.enabled = NO;
            [self setupChooseImageButton];
        });
        NSData *fullImageData = UIImagePNGRepresentation([UIImageManipulator scaleImage:[info objectForKey:@"UIImagePickerControllerOriginalImage"] toSize:CGSizeMake(800, 600)]);
        [fullImageData writeToFile:fullPath atomically:NO];

        dispatch_async(dispatch_get_main_queue(), ^{
            imageButton.enabled = YES;
            object.imagePath = fullPath;
        });

        if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
            UIImageWriteToSavedPhotosAlbum([info objectForKey:@"UIImagePickerControllerOriginalImage"], self, nil, nil);
        }

    });
    dispatch_release(image_queue);
}

Respuestas a la pregunta(1)

Su respuesta a la pregunta