Pregunta

he estado usando

NSMutableData* mutableData = [NSMutableData dataWithLength: someLength];
void* bitmapData = [mutableData mutableBytes];
CGContextRef context = CGBitmapContextCreate(bitmapData,...);
// ...use context
CGContextRelease(context);

Tengo un grupo de liberación automática, pero cuando miro esto en Instrumentos, mutableData no parece haber sido desasignado.
Pensé en usar alloc/init como a continuación, pero no estoy seguro si enviar release purgaría bitmapData también.

NSMutableData* mutableData = [[NSMutableData alloc] initWithLength: someLength];
void* bitmapData = [mutableData mutableBytes];
[mutableData release];
//...

¿Cuál es la forma correcta de usar? NSMutableData ¿aquí?

Pensé en usar NSMutableData en lugar de malloc() y free() Sería conveniente porque se publicará automáticamente.pero ahora no estoy seguro si eso es cierto.

¿Fue útil?

Solución

Cuando tu dices mutableData no parece haber sido desasignado, ¿quieres decir en el momento de CGContextRelease(), ¿O quieres decir que nunca se desasigna y se filtra cada vez que ejecutas esto?

En su primer ejemplo, no esperaría mutableData desasignar hasta que el grupo de liberación automática se agote (generalmente al final del ciclo de eventos), porque usó -dataWithLength:.En su segundo ejemplo, no está definido si mutableData sería liberado.el llamado a -mutableBytes podría aplicar retención y liberación automática para garantizar que el puntero sea válido para el resto del bucle de eventos (esto es bastante común con este tipo de métodos), pero los documentos no lo dicen, por lo que su segundo ejemplo es un comportamiento indefinido si usa bitmapData más tarde.

Ahora si mutableData fugas, entonces probablemente lo esté reteniendo en exceso en otro lugar.

Otros consejos

Pedir una instancia de NSMUTABLEDATA por su mutable Bytes simplemente devuelve un puntero al búfer existente (ya asignado) que administra para usted. No tiene ningún efecto en la memoria desde una perspectiva de gestión.

Entonces, en su primer ejemplo, el hecho de que MutableATA no parezca estar desaconsejado al mirarlo en instrumentos podría estar relacionado con el entorno de la piscina de autorreelo en ese momento. ¿El código que usa mutableata de esa manera tiene un nsautoreleasepool en su lugar? ¿Ves advertencias en la consola como "Autorelease llamado sin piscina en su lugar; solo goteando"? Si es así, solo necesita envolver el código en:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// bitmap drawing code here
[pool drain];

En la segunda muestra, podría usar Alloc/Init en la instancia de NSMUTABLEDATA, pero necesitaría liberarlo después de que haya terminado de usar el puntero que obtiene de MutableBytes. El puntero apuntará a la memoria de desaconsación (liberada) después de que llame la liberación, y acceder a ella dará como resultado el temido exc_bad_access.

Además, usar Malloc/Free probablemente sería mi primera opción aquí, ya que puede ser muy explícito sobre cómo y cuándo se asigna y libera la memoria. NSMUTABLEDATA + AUTORELEASE realmente no le está comprando nada excepto algo de sobrecarga, si no está utilizando el objeto para nada más.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top