填写带有UIImage对象的NSMutableArray时遇到问题

时间:2010-01-24 01:19:38

标签: objective-c iphone multithreading uiimage nsmutablearray

尝试使用UIImages填充NSMutableArray时,我遇到了一个令人困惑的问题。

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 :(得分:0)

不确定这是否是问题,但您可能应该通知代理主线程上的更改,而不是运行NSOperation的线程。

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

同样对于最后一条消息。如果委托正在修改与UIKit相关的任何内容,则必须在主线程上调用

答案 1 :(得分:0)

有人可能会假设NSMutableArray会处理添加到它的对象的内存管理,但也许是因为你正在处理C级Quartz helpers / Core包装器,但情况可能并非如此。

在我尝试过的其他图像处理方法中,如果它们涉及线程,它们通常包含在自动释放池中。

您是否尝试过在finalImage上尝试发布/自动释放?

答案 2 :(得分:0)

找出问题所在。原来是支持 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);