UIImageJPEGRepresentation - проблема с выпуском памяти - PullRequest
4 голосов
/ 16 апреля 2010

В приложении для iPhone мне нужно отправить jpg по почте с максимальным размером 300Ko (у меня нет максимального размера mail.app, который может быть, но это другая проблема). Для этого я пытаюсь снизить качество, пока не получу изображение под 300Ko.

Для того, чтобы получить хорошее значение качества (ressionLevel), которое дает мне JPG под 300Ko, я сделал следующий цикл. Это работает, но каждый раз, когда выполняется цикл, объем памяти увеличивается по сравнению с исходным размером моего jpg (700Ko), несмотря на «[tmpImage release];».

float compressionLevel = 1.0f;
int size = 300001;
while (size  > 300000) {
    UIImage *tmpImage =[[UIImage alloc] initWithContentsOfFile:[self fullDocumentsPathForTheFile:@"imageToAnalyse.jpg"]];
    size = [UIImageJPEGRepresentation(tmpImage, compressionLevel) length];
    [tmpImage release];
        //In the following line, the 0.001f decrement is choose just in order test the increase of the memory  
    //compressionLevel = compressionLevel - 0.001f;
    NSLog(@"Compression: %f",compressionLevel);
} 

Любые идеи о том, как я могу снять это, или почему это происходит? спасибо

1 Ответ

9 голосов
/ 17 апреля 2010

По крайней мере, нет смысла выделять и отпускать изображение при каждом прохождении цикла. Он не должен пропускать память, но в этом нет необходимости, поэтому переместите alloc / init и выпустите из цикла.

Кроме того, данные, возвращаемые UIImageJPEGRepresentation, автоматически высвобождаются, поэтому они будут зависать до тех пор, пока не истечет текущий пул релизов (когда вы вернетесь в основной цикл событий). Рассмотрите возможность добавления:

NSAutoreleasePool* p = [[NSAutoreleasePool alloc] init];

в верхней части цикла и

[p drain] 

в конце. Таким образом, вы не потеряете всю промежуточную память.

И, наконец, линейный поиск оптимальной настройки сжатия, вероятно, довольно неэффективен. Вместо этого выполните бинарный поиск.

...