2

Я используюИспользуя байты экземпляра NSMutableData, позволяя ему быть autoreleased

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

У меня есть autorelease бассейн на месте, но при взгляде на это инструменты, mutableData не кажется, быть освобожден.
Я думал об использовании alloc/init, как показано ниже, но я не уверен, что отправка release очистит bitmapData.

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

Что такое правильный способ использования NSMutableData здесь?

Я думал, что использовать NSMutableData вместо malloc() и free() было бы удобно, потому что он будет автореализован. но теперь я не уверен, что это правда.

ответ

1

Когда вы говорите, что mutableData, похоже, не освобождается, вы имеете в виду в точке CGContextRelease(), или вы имеете в виду, что он никогда не освобождает вас от утечки при каждом запуске?

В вашем первом примере вы не ожидали, что mutableData освободится, пока пул авторекламы не будет истощен (как правило, в конце цикла событий), поскольку вы использовали -dataWithLength:. В вашем втором примере не определено, будет ли выпущено mutableData. Вызов -mutableBytes может применить сохранение и авторекламу, чтобы гарантировать, что указатель действителен для остальной части цикла событий (это довольно часто встречается с этими методами), но документы не говорят, поэтому ваш второй пример - неопределенное поведение если вы позже используете bitmapData.

Теперь, если у вас mutableData утечки, тогда вы, вероятно, передержите его в другом месте.

+0

Да, он никогда не освобождается даже после CGContextRelease(). Я не передаю необработанные данные или NSMutableData ко всему, кроме функции создания контекста. – eugene

+0

Под «никогда» вы подразумеваете, даже после того, как цикл событий завершен, так что, когда вы вызываете это несколько раз, ваше общее использование памяти продолжает расти? –

+0

grr, имел другие утечки где-то в другом месте, которое сохраняет изображение, созданное из контекста, не уверен, что сохраняет исходный байт, следовательно, mutabledata. Но, удалив другие утечки, инструмент не показывает mutableData как живой. Возможно, инструменты были смущены – eugene

0

Запрашивая экземпляр NSMutableData для его mutableBytes просто возвращает указатель на существующий (уже выделенный) буфер, который он управляет для вас. Это не влияет на память с точки зрения управления.

Итак, в вашем первом примере тот факт, что mutableData, по-видимому, не освобождается, если смотреть на него в Инструментах, может быть связан с окружением пула автозапуска в то время. Имеет ли код, использующий mutableData таким образом, NSAutoreleasePool? Вы видите предупреждения в консоли, такие как «автореклама, вызванная без пула на месте, просто утечка»? Если да, то вам просто нужно обернуть код:

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

Во втором примере, вы могли бы использовать Alloc/инициализации на экземпляре NSMutableData, но вам нужно будет освободить его после того, как вы сделали с помощью указателя вам получить из mutableBytes. Указатель укажет на освобожденную (освобожденную) память после вызова release, и доступ к ней приведет к ужасному EXC_BAD_ACCESS.

Кроме того, использование malloc/free, вероятно, будет моим первым выбором здесь, так как вы получите очень четкое представление о том, как и когда выделена и освобождена память. NSMutableData + autorelease на самом деле не покупает вам ничего, кроме некоторых накладных расходов, если вы не используете объект ни для чего другого.