ImageIO:CGImageRead_mapData'open'失败错误= 24(打开文件太多)

时间:2011-10-10 10:47:39

标签: iphone ios ipad memory

我正在使用Uikit + Uiimages开发一个小型游戏应用。在正常情况下我的应用程序运行没有任何问题。但是当我轻率地使用时,它会因错误而崩溃

<Notice>: ImageIO: CGImageRead_mapData 'open' failed '/var/mobile/Applications/01E69C96-CF79-466F-93AB-3A6752AF1295/PictureBook.app/NextPage.png'

<Notice>: error = 24 (Too many open files).

我将在使用完成后发布所有图片视图和视频。我用泄漏工具测试了我的应用程序。也没有泄漏。没有警告,没有潜在的泄漏等......

我搜索了一个很好的答案,但我还没有得到合适的答案。谁知道答案,请回复。我在下面发布了一些代码。

- (NSMutableArray *)flowerArray {

if (!_flowerArray) {

_flowerArray = [[NSMutableArray alloc]init];

for (int i = 1; i <= 5; i++) {

UIImage *flowerIm = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"01_Flower_0%d.png",i] ofType:nil]];

[_flowerArray addObject:flowerIm];

[flowerIm release];

}

}

return _flowerArray;
}


-(void)flowerImagesAnimate {

self.flowerImage.animationImages = self.flowerArray;

self.flowerArray = nil;

self.flowerImage.animationDuration = 1.0;

self.flowerImage.animationRepeatCount = 3;

[self.flowerImage startAnimating];

}



-(void)playerPrepare
{

[self.view addSubview:[self.presentView playerPrepare]];

}
-(void)wakeUPPanjo
{
NSString *url = [[NSBundle mainBundle] pathForResource:@"01_Anim" 
ofType:@"mp4"];

NSURL *movieURL = [NSURL fileURLWithPath:url];



self.presentView.player = [[MPMoviePlayerController alloc] 
initWithContentURL:movieURL];




[[NSNotificationCenter defaultCenter] 
addObserver:self
selector:@selector(movieFinishedCallback 
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.presentView.player];

[self.presentView.player prepareToPlay];

[self performSelector:@selector(playerPrepare) withObject:nil afterDelay:0.5];

wakeUpTimer = nil;


}


-(void)viewLoad
{

wakeUpTimer = [NSTimer scheduledTimerWithTimeInterval:videoDelay target:self selector:@selector(wakeUPPanjo) userInfo:nil repeats:NO];

[self performSelector:@selector(flowerImagesAnimate) withObject:nil afterDelay:flowerPopupDelay];
}

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.

[self performSelectorOnMainThread:@selector(viewLoad) 
withObject:nil 
waitUntilDone:false];
}

3 个答案:

答案 0 :(得分:5)

尝试在整个项目中使用initWithContentsOfFile来加载图片而不是UIImage的imageNamed。 如果您有太多可能导致严重问题的图像,imageNamed会自动释放,Apple本身建议减少使用自动释放的对象。

  

iPhone OS注意:因为在iPhone OS上,应用程序在更受内存限制的环境中执行,所以在应用程序创建许多对象的方法或代码块(例如,循环)中不鼓励使用自动释放池。相反,您应该尽可能明确地释放对象。

答案 1 :(得分:5)

从缓存目录中读取图像数据时出现相同的错误。

当您的图片包含在App-Project中时,afzal的建议是最好的解决方案。

但是当直接从缓存文件夹中读取它时,请不要使用

[UIImage initWithContentsOfFile:<image-file-path>];

特别是当您从Cache-Folder中加载像一堆图像时,因为它可能会破坏您的一些图像,并且它们看起来可能只有一半只加载了一半。加载图像数据,如下所示

NSData *data = [NSData dataWithContentsOfFile:<image-file-path>];
UIImage *image = [UIImage imageWithData:data];

这对你的任何图像都不会有任何损坏。

我猜,它是因为一次打开了许多输入流。

答案 2 :(得分:0)

运行sudo fs_usage -f filesys PictureBook。在第二列中,文件应该“打开”和“关闭”,但是您的应用程序有太多“打开”而太少“关闭”,因为您打开文件太快或泄漏文件描述符。也许你没有保留_flowerArray并且它每次都被重建?目前还不清楚。查找有问题的文件并添加一些日志。

如果您使用UIImage的imageNamed代替initWithContentsOfFile,文件将被缓存并重复使用,并且它不会那么容易崩溃,但无论如何,很可能是您泄漏/开得太快了。