Использование байтов экземпляра NSMutableData при разрешении его автоматического выпуска - PullRequest
2 голосов
/ 04 февраля 2011

Я использую

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

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

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

Как правильно использовать NSMutableData здесь?

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

Ответы [ 2 ]

1 голос
/ 04 февраля 2011

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

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

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

0 голосов
/ 04 февраля 2011

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

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

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

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

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

...