2010-01-24 1 views
0

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

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, поэтому он не блокирует интерфейс. Еще один интересный аспект здесь заключается в том, что когда массив изображений, отправленный с , операцияCompletedWithImages давала мне массив повторяющихся изображений, которые я пытался использовать сообщение send_mage и сохранял изображения в другом массиве внутри объекта делегата (думая, выпуск). Это дало мне те же результаты.

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

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

ответ

0

Выяснилось, что проблема. Оказалось, что проблема с поддержкой данные указатель.

Куда раньше я обращался к данным каждый раз, думая, что он будет перебирать и перезаписывать новое содержимое, а новое содержимое будет подключено к моему 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

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

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

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

+0

Спасибо! это определенно шаг в правильном направлении. Когда я выполняю селектор sendImage в основном потоке, я определенно получаю правильные изображения. Теперь я добавляю эти изображения в массив в объекте делегирования (основной поток). Проблема в том, что как только все они добавлены, и я пытаюсь их пересмотреть, они все одинаковые. Очень странно. Поэтому я получаю правильные изображения из фонового потока, но каким-то образом массив просто сохраняет копии последнего полученного изображения ... –

+0

Что вы подразумеваете под «все-таки»? Все ли изображения имеют один и тот же контент или один и тот же экземпляр *? Проверьте значения указателя, хранящиеся в вашем массиве! – PfhorSlayer

+0

Оформление одинаково. Интересно то, что, хотя указатели UIImage & CGImageRef уникальны в массиве, NSObject -> ISA-адрес для каждого UIImage в массиве одинаковый. Не уверен, что это значит, но это единственная связь, которую я смог найти до сих пор. Я также попытался объявить 10 экземпляров экземпляров UIImage и сохранить там набор из десяти изображений. Это сработало! Таким образом, проблема возникает только при хранении изображений в массиве (я попробовал NSArray, CFArray и C array - UIImage * images [...]). –

0

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

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

Вы пробовали экспериментировать с выпуском/autorelease на finalImage?

+0

Я играл с изменением количества удержаний безрезультатно. Я полагал, что это был выстрел в темноте, так как я не мог понять, почему это приведет к дублированию объектов в массиве. Что действительно заставляет мою голову вращаться с этим - в объекте делегата (в основном потоке) я попытался вытащить CGImageRef из каждого UIImage, поскольку они были отправлены через sendImage и выделены новые UIImage с CGImageRef, чтобы получить новую копию до добавление в массив. Я STILL получаю массив одного и того же изображения снова и снова (все еще добавлено последнее изображение). –

Смежные вопросы