【发布时间】:2014-04-09 03:06:31
【问题描述】:
我目前正在开发一个 iPad 应用程序,它将 ~250 UIImages 加载到 UIButtons(然后更改颜色),创建世界地图 - 每个国家都有自己的按钮和相应的图像 - 当加载游戏。我遇到的问题是,在视网膜 iPad 上,应用程序在加载图像时使用了大约 650MB 的 RAM,这太疯狂了。
当应用最初加载游戏时,它使用以下代码将图像设置为按钮(Territory 是UIButton 的子类)。
//Initialize the arrays of each territory and add an action to the territory
for (int i = (int)territoryArray.count - 1; i >= 0; i--) {
@autoreleasepool {
//Cast the object into a territory object
Territory *ter = (Territory *)[territoryArray objectAtIndex:i];
//Set the territory's image
[ter setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@T%i.png", [defaults objectForKey:@"Current_Map"], i + 1] ofType:nil]] forState:UIControlStateNormal];
}
}
这会导致以下内存使用情况。峰值在循环运行时出现,但即使块被@autoreleasepool 包围也不会消失。注意ImageIO 正在使用内存:
该屏幕截图是在领土的图像文件中具有原始颜色时拍摄的。我正在使用来自MGImageUtilities 的UIImage+Tint 库为图像着色。使用该库时,使用以下代码:
[ter setImage:[[ter imageForState:UIControlStateNormal] imageTintedWithColor:[UIColor colorWithRed:[[colors objectAtIndex:0] floatValue]/255.0 green:[[colors objectAtIndex:1] floatValue]/255.0 blue:[[colors objectAtIndex:2] floatValue]/255.0 alpha:1.0]] forState:UIControlStateNormal];
加载所有图像后,在另一个循环中使用此代码(在另一个函数中用@autoreleasepool 括起来)时,会发生以下内存使用情况。注意CG raster data 正在使用内存。
不知道为什么使用内存的东西不一样。
我在 Apple 开发者论坛上 posted a thread 上也发布了这个问题。
我还联系了 Apple Developer TSI,他们建议使用“延迟图像加载”。我对此进行了调查,但我还没有找到在非基于页面的UIScrollView 上执行此操作的方法。
在这一点上,我几乎不知道如何解决这个问题。经过数小时的努力,我已经尝试了我能想到的一切,但我似乎无法提出任何可行的解决方案。如果有人可以帮助我,我将不胜感激。如果您想查看更多信息或代码,请告诉我,我很乐意发布。提前感谢您的帮助。
编辑:
我一直在试验,我正在使用scrollViewDidScroll: 中的以下代码。它似乎正在工作,但内存没有被释放,它继续上升。想法?
CGRect currentF = [scrollView convertRect:scrollView.bounds toView:scrollView.contentView];
//Loop through all territories and determine which need to be rendered
for (int i = (int)territoryArray.count - 1; i >= 0; i--) {
@autoreleasepool {
//See if the territory is on-screen
if (CGRectIntersectsRect(currentF, [[territoryArray objectAtIndex:i] frame])) {
//See if the territory needs an image
if ([[territoryArray objectAtIndex:i] image] == nil) {
//Set the territory's image
[[territoryArray objectAtIndex:i] setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@T%i.png", [defaults objectForKey:@"Current_Map"], i + 1] ofType:nil]] forState:UIControlStateNormal];
}
} else {
//Remove the territory's image, it is off-screen
[[territoryArray objectAtIndex:i] setImage:nil forState:UIControlStateNormal];
}
}
}
【问题讨论】:
-
公平地说,你不能指望一次加载 250 张图像而没有像这样的内存气球。您需要某种增量图块加载。
标签: ios objective-c xcode uiimage