Проблема заполнения NSMutableArray w / UIImage объектов - PullRequest
0 голосов
/ 24 января 2010

У меня непонятная проблема при попытке заполнить массив NSMutableArray UIImages.

CGBitmapInfo bitmapInfo = kCGBitmapByteOrderMask;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

while(...)     // <--- Iterates through data sets
{

          CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, data, numBytes, NULL);
          CGImageRef cImage = CGImageCreate(iw, ih, 8, 32, 4 * iw, colorSpace, bitmapInfo, provider, NULL, NO, renderingIntent);
          UIImage *finalImage = [UIImage imageWithCGImage:cImage];


          [images addObject:finalImage]; // <--- Declared and instantiated earlier

          [delegate sendImage:finalImage];

          CGImageRelease(cImage);
          CGDataProviderRelease(provider);
}

CGColorSpaceRelease(colorSpace);

[delegate operationCompletedWithImages:images];

Вот так у меня работает код. Итак, у меня в основном есть функция, выполняющаяся в операторе while, которая возвращает следующий набор растровых данных, затем я создаю UIImage и сохраняю его в изменяемый массив.

Я проверил это, записав каждый файл на диск и затем получив доступ к ним, что привело к правильному набору изображений. Проблема в том, что при использовании массива для хранения данных в памяти, при доступе к любому объекту изображения в массиве я получаю одно и то же точное изображение снова и снова. Изображение также всегда является последним изображением набора.

Я попытался протестировать содержимое, установив массив в качестве массива анимации UIImageView и используя NSTimer для циклического перемещения содержимого. В любом случае, это снова и снова одно и то же изображение (последнее изображение).

Эта операция выполняется внутри подклассного объекта NSOperation, поэтому он не блокирует интерфейс. Другой интересный аспект заключается в том, что когда массив изображений, отправленный с помощью operationCompletedWithImages , давал мне массив дублированных изображений, я попытался использовать сообщение sendImage и сохранить изображения в другом массиве внутри делегата. объект (думая, может быть, это была проблема с потоками). Это дало мне те же результаты.

Я застрял на этом более недели без прогресса. Я никогда не видел ничего подобного, и я не могу найти кого-то еще, у кого была похожая проблема. Я был бы рад предоставить дополнительную информацию, если кто-то считает, что это поможет в решении этой проблемы.

Если бы кто-нибудь мог оказать какую-либо помощь, я был бы очень признателен.

Ответы [ 3 ]

0 голосов
/ 24 января 2010

Можно предположить, что NSMutableArray будет обрабатывать управление памятью объекта, добавляемого к нему, но, возможно, из-за того, что вы имеете дело с помощниками Кварца уровня C / оболочками Core, это может быть не так.

В других методах манипулирования изображениями, с которыми я экспериментировал, они обычно заключаются в пул авто-релизов, если они связаны с потоками.

Вы пробовали экспериментировать с выпуском / авто-выпуском на финальном изображении?

0 голосов
/ 25 февраля 2010

Разобрался с проблемой. Оказалось, проблема с указателем data .

Где раньше я обращался к данным каждый раз, думая, что они будут повторяться и перезаписываться новым содержимым, а новое содержимое будет подключено к моему CGDataProviderRef. Это было не так, я в основном поставил указатель на те же данные поддержки для провайдера. Решением было скопировать данные в объект NSData и использовать эту копию для DataProvider.

Так что вместо:

CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, data, numBytes, NULL);

Это будет:

NSData *pxData = [[NSData alloc] initWithBytes:pFrameRGB->data length:numBytes];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)pxData);
0 голосов
/ 24 января 2010

Не уверен, что это проблема, но вы, вероятно, должны уведомлять вашего делегата об изменениях в главном потоке, а не в потоке, в котором работает NSOperation.

[delegate performSelectorOnMainThread:@selector(sendImage:) withObject:finalImage waitUntilDone:YES];

И для последнего сообщения. Если делегат изменяет что-либо, связанное с UIKit, он должен быть вызван в главном потоке!

...