El object lanzado con CFRelease provoca un crash obvio, pero solo raramente

Tengo el siguiente método:

+ (NSString*) getMD5HashFromFile:(NSString*)filePath { CFStringRef md5hash = FileMD5HashCreateWithPath((CFStringRef)filePath, FileHashDefaultChunkSizeForReadingData); NSString *hashStr = (NSString*)md5hash; CFRelease(md5hash); return hashStr; } 

Estaba recibiendo lockings aleatorios en el simulador, aproximadamente 1 en 20-30 ejecuciones. El hecho de que esto no fuera consistente no me ayudó a cavar más profundo antes.

Ahora que veo el código nuevamente, parece obvio que md5hash se libera antes de ser devuelto, lo que significa que el object devuelto está invalidado. El valor devuelto se usa en otro método de manera consistente que se bloquea a veces, pero no siempre. Mi pregunta es por qué esto solo sucede raramente y no siempre.

¿Tiene algo que ver con la combinación del código Obj-C y C y la forma en que funcionan las agrupaciones autorelease?

Nota: El error parece NSString *hashStr = [NSString stringWithString:(NSString*)md5hash] utilizando NSString *hashStr = [NSString stringWithString:(NSString*)md5hash] , lo que tiene total sentido para mí.

El hecho de que se suelte un trozo de memory y se desasigne no significa que se devuelva de inmediato al sistema operativo. Su aplicación puede retenerla durante un período de time arbitrario en function de numerosos factores y en varias capas. El sistema operativo tiene cosas más importantes que hacer a veces que reclamar cada pieza de memory que suelte y podría pedirlo nuevamente en medio segundo. Acceder a la memory que ha llamado gratis (), pero técnicamente propia, no genera una señal. Es por eso que MallocScribble existe. Sobreescribe la memory que liberas con la papelera (0x55) para que resulte más evidente cuando usas la memory liberada.

Prueba lo siguiente:

 char *foo = malloc(100); strcpy(foo, "stuff"); free(foo); printf("%s", foo); 

La mayor parte del time funcionará bien, a pesar de estar completamente equivocado. Ahora, edite su esquema> Diagnóstico y habilite el garabato. Vuelva a ejecutar y verá un montón de "U" (0x55) que indica que está leyendo una tontería. Pero aún no se cuelga.

Puede que te interese Matt Gallagher's Una mirada a cómo malloc funciona en Mac para un poco más sobre el tema.

CFRelease argumento CFRelease no debe ser NULL.

Si el argumento CFRelease es NULL, esto provocará un error de time de ejecución y su aplicación se bloqueará

 if(md5hash) CFRelease(md5hash); 
 +(NSString*) getMD5HashFromFile:(NSString*)filePath { CFStringRef md5hash = FileMD5HashCreateWithPath((CFStringRef)filePath, FileHashDefaultChunkSizeForReadingData); NSString *hashStr = [(NSString*)md5hash copy]; CFRelease(md5hash); return [hashStr autorelease]; } 

asegúrese de conservar el valor devuelto en la persona que llama si necesita agarrarlo durante un período de time prolongado.