Debe drawInRect: para que se ejecute un contexto separado en el hilo principal?

[actualización: este problema ha sido resuelto; el problema no estaba endrawInRect: pero enUIGraphicsBeginImageContext()]

En mi aplicación, estoy tomando un montón de imágenes grandes, recortándolas al tamaño de las miniaturas y almacenando las miniaturas para obtener una vista previa.

Tenga en cuenta que estoy haciendo esto en un contexto de imagen separado: esto esno acerca de volver a dibujar unUIView eso está en la pantalla.

Este código es bastante intensivo, así que lo estoy ejecutando en un hilo separado. La escala real se ve así, y es una implementación de categoría además deUIImage:

- (UIImage *) scaledImageWithWidth:(CGFloat)width andHeight:(CGFloat)height
{
    CGRect rect = CGRectMake(0.0, 0.0, width, height);
    UIGraphicsBeginImageContext(rect.size);
    [self drawInRect:rect]; // <-- crashing on this line
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return scaledImage;
}

Esto se llama desde un método separado, que recorre las imágenes a su vez y realiza el procesamiento. La llamada real al método anterior se ve así:

UIImage *small = [bigger scaledImageWithWidth:24.f andHeight:32.f];

Todo esto funciona la mayor parte del tiempo, pero ocasionalmente recibo unEXC_BAD_ACCESS.

Traza inversa:

#0  0x330d678c in ripc_RenderImage ()
#1  0x330dd5aa in ripc_DrawImage ()
#2  0x300e3276 in CGContextDelegateDrawImage ()
#3  0x300e321a in CGContextDrawImage ()
#4  0x315164c8 in -[UIImage drawInRect:blendMode:alpha:] ()
#5  0x31516098 in -[UIImage drawInRect:] ()
#6  0x0000d6e4 in -[UIImage(Scaling) scaledImageWithWidth:andHeight:] (self=0x169320, _cmd=0x30e6e, width=48, height=64) at /Users/me/Documents/svn/app/trunk/Classes/UIImage+Scaling.m:20
#7  0x00027df0 in -[mgMinimap loadThumbnails] (self=0x13df00, _cmd=0x30d05) at /Users/me/Documents/svn/app/trunk/Classes/mgMinimap.m:167
#8  0x32b15bd0 in -[NSThread main] ()
#9  0x32b81cfe in __NSThread__main__ ()
#10 0x30c8f78c in _pthread_start ()
#11 0x30c85078 in thread_start ()

[actualización 4] Cuando ejecuto esto en el simulador, y ocurre este problema, la consola también muestra lo siguiente:

// the below is before loading the first thumbnail
<Error>: CGContextSaveGState: invalid context
<Error>: CGContextSetBlendMode: invalid context
<Error>: CGContextSetAlpha: invalid context
<Error>: CGContextTranslateCTM: invalid context
<Error>: CGContextScaleCTM: invalid context
<Error>: CGContextDrawImage: invalid context
<Error>: CGContextRestoreGState: invalid context
<Error>: CGBitmapContextCreateImage: invalid context
// here, the first thumbnail has finished loading and the second one
// is about to be generated
<Error>: CGContextSetStrokeColorWithColor: invalid context
<Error>: CGContextSetFillColorWithColor: invalid context

Mi instinto es que ocasionalmente termino tratando dedrawInRect: mientras que el sistema operativo también está tratando de dibujar algo, lo que ocasionalmente provoca un bloqueo. Siempre supuse que, siempre y cuando no dibujes en la pantalla real, esto es aceptable, ¿no es así? O si es el caso, ¿alguna idea de lo que podría estar causando esto?

Actualización (r2): olvidé mencionar que esta aplicación se está ejecutando con limitaciones de memoria bastante severas (tengo muchas imágenes cargadas en un momento dado y estas se intercambian dentro / fuera), por lo que este puede ser un caso de ejecución sin memoria (sigue leyendo, no lo es). Sin embargo, no estoy seguro de cómo verificar eso, por lo que pensar en esto también sería bienvenido. Verifiqué esto reduciendo drásticamente la cantidad de imágenes que se están cargando y agregando una verificación para asegurarme de que estén correctamente desasignadas (lo están y el bloqueo aún ocurre).

Actualización 3: pensé que encontré el problema. A continuación se muestra la respuesta que escribí, antes de que el accidente volviera a ocurrir:

El código (después de publicar esta pregunta) ocasionalmente comenzaría a salir con el código de salida0, y a veces con código de salida10 (SIGBUS). 0 significa "sin error", por lo que fue extremadamente extraño.10 parece significar un poco de todo, por lo que tampoco fue útil. losdrawInRect: Sin embargo, la llamada fue un gran indicio cuando ocurrió el accidente allí.

El bucle para obtener las miniaturas generaba muchas imágenes publicadas automáticamente. Tenía un grupo de liberación automática pero estaba envolviendo todo el ciclo for. Agregué un segundo grupo de liberación automática dentro delfor lazo:

- (void)loadThumbnails
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    for (...) {
        NSAutoreleasePool *cyclePool = 
           [[NSAutoreleasePool alloc] init]; // <-- here
        UIImage *bigger = ...;
        UIImage *small = [bigger scaledImageWithWidth:24.f andHeight:32.f];
        UIImage *bloated = [i scaledImageWithWidth:48.f andHeight:64.f];
        [cyclePool release]; // <-- ending here
    }
    [pool release];
}

Pensé que lo anterior solucionó el problema, hasta que ejecuté la aplicación y me chocó con el "código de salida 0" nuevamente justo antes. De vuelta al tablero de dibujo ...

Respuestas a la pregunta(3)

Su respuesta a la pregunta