我正在为UIImageView创建图像数组,因此我可以使用[_myImageView startAnimating];
方法。我想,如果我像这样缓存(预加载),动画就会流畅。
但在我看到的乐器中,该游戏已被解除分配,但仍然分配了太多内存 - 我认为这些UIGraphicsBeginContext内容有一些片段。
我使用它是否正确,还有其他一些方法可以解除它吗? 提前谢谢!
- (NSMutableArray *)generateCachedImageArrayWithFilename:(NSString *)filename extension:(NSString *)extension andImageCount:(int)count
{
_imagesArray = [[NSMutableArray alloc] init];
_fileExtension = extension;
_animationImageName = filename;
_imageCount = count;
for (int i = 0; i < count; i++)
{
NSString *tempImageNames = [NSString stringWithFormat:@"%@%i", filename, i];
NSString *imagePath = [[NSBundle mainBundle] pathForResource:tempImageNames ofType:extension];
UIImage *frameImage = [self loadRetinaImageIfAvailable:imagePath];
UIGraphicsBeginImageContext(frameImage.size);
CGRect rect = CGRectMake(0, 0, frameImage.size.width, frameImage.size.height);
[frameImage drawInRect:rect];
UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[_imagesArray addObject:renderedImage];
if (_isDoublingFrames)
{
[_imagesArray addObject:renderedImage];
}
else if (_isTriplingFrames)
{
[_imagesArray addObject:renderedImage];
[_imagesArray addObject:renderedImage];
}
NSLog(@"filename = %@", filename);
}
return _imagesArray;
}
- (UIImage *)loadRetinaImageIfAvailable:(NSString *)path
{
NSString *retinaPath = [[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@@2x.%@", [[path lastPathComponent] stringByDeletingPathExtension], [path pathExtension]]];
if ([UIScreen mainScreen].scale == 2.0 && [[NSFileManager defaultManager] fileExistsAtPath:retinaPath] == YES)
return [[UIImage alloc] initWithCGImage:[[UIImage imageWithData:[NSData dataWithContentsOfFile:retinaPath]] CGImage] scale:2.0 orientation:UIImageOrientationUp];
else
return [UIImage imageWithContentsOfFile:path];
}
-(void) dealloc
{
[_imagesArray removeAllObjects];
_imagesArray = nil;
}
答案 0 :(得分:0)
我的内存问题类似于你写的以及我在你的代码中尝试的内容
1)使用@autoreleasepool
在@autoreleasepool { }
中包装循环的方法或内容,以创建一个将在方法完成后释放的本地池。在你的情况下,我觉得包裹循环更好:
for (int i = 0; i < count; i++)
{
@autoreleasepool {
// the loop code
...
}}
2)杀死[UIImage imageNamed]
使用imageNamed
将准备一个缓存(取决于图像的大小),除非您收到内存警告,否则它将永远不会从内存中刷新。即使你设置myImage.image = nil,图像仍然在内存中。 XCode的Intruments工具Allocations视图将很好地展示它。您可以做的是像这样初始化UIImage
,iOS不会缓存图像:
image = [UIImage imageWithContentsOfFile:fullpath];
您可以在imageNamed
下的代码中使用loadRetinaImageIfAvailable
。
保持这两种方法,让我们再次检查一下!