将 uiimage 设置为 nil 不会使用 ARC 释放内存
Posted
技术标签:
【中文标题】将 uiimage 设置为 nil 不会使用 ARC 释放内存【英文标题】:Setting uiimage to nil doesn't release memory with ARC 【发布时间】:2011-11-02 07:46:19 【问题描述】:我有一个滚动视图,可以在滚动页面时显示不同的图像,例如 PhotoScroller。我正在使用 ARC。当有人滚动到另一个页面时,我将当前未显示的 UIImageView 的图像属性设置为 nil,因为(试图)避免内存崩溃,这种情况仍在发生。然后当用户滚动到一个新页面时,该页面的图像设置为 UIImageView 的图像属性,以及它之前和之后的页面(为了流畅查看)。页面的 UIImage 都保存在一个数组中。然而,当我滚动页面时,内存使用量不断上升,好像将 UIImageView 的 image
属性设置为 nil 并没有从内存中释放它。我使用initWithContentsOfFile
来初始化我的 UIImages。我也尝试了imageNamed
和imageWithContentsOfFile
,但没有运气。这是我的滚动视图代码:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
int indexShown = self.scrollView.bounds.origin.x / kScrollObjWidth;
for(NSNumber *index in indexesToRemove)
UIImageView *imgViewToRemove = [[self.scrollView subviews] objectAtIndex:[index intValue]];
imgViewToRemove.image = nil;
[indexesToRemove removeAllObjects];
UIImageView *imgViewToReplace = [[self.scrollView subviews] objectAtIndex:indexShown];
[imgViewToReplace setImage:[pageUIImagesArr objectAtIndex:indexShown]];
[indexesToRemove addObject:[NSNumber numberWithInt:indexShown]];
if(indexShown != 0 && ![[[self.scrollView subviews] objectAtIndex:indexShown-1] image])
imgViewToReplace = [[self.scrollView subviews] objectAtIndex:indexShown-1];
[imgViewToReplace setImage:[pageUIImagesArr objectAtIndex:indexShown-1]];
[indexesToRemove addObject:[NSNumber numberWithInt:indexShown-1]];
if(indexShown != kNumImages-1 && ![[[self.scrollView subviews] objectAtIndex:indexShown+1] image])
imgViewToReplace = [[self.scrollView subviews] objectAtIndex:indexShown+1];
[imgViewToReplace setImage:[pageUIImagesArr objectAtIndex:indexShown+1]];
[indexesToRemove addObject:[NSNumber numberWithInt:indexShown+1]];
currentView = [[self.scrollView subviews] objectAtIndex:indexShown];
//check which view is being shown`
【问题讨论】:
我发现图像的创建方式有很大的不同。而不是 [UIImage imageNamed:xxxxx];我使用 NSString *filePath = [[NSBundle mainBundle] pathForResource:imageFileNameTemp ofType:@"png"]; UIImage *image = [[UIImage alloc] initWithContentsOfFile:filePath];这节省了我大约 50% 的 Live Bytes 和 #Living 对象。我使用分配工具进行了检查。不使用静态初始化器时,您没有看到更好的结果,这让我感到困惑。 【参考方案1】:页面的 UIImage 都保存在一个数组中。
当您将UIImageView
的属性设置为nil
时,UIImage
不会被释放,因为数组仍然持有对它们的引用。至于内存增长,可能是正在分配的其他东西。我建议您查看 Instrument 的对象分配工具,以跟踪滚动时的具体增长情况。
【讨论】:
嗯。但是当应用程序启动时,我将 uiimages 加载到数组中。我只将它们设置为 uiimageview 的图像属性,然后将其设置回 nil。我想如果它来自阵列,它只会在启动时崩溃。我确实检查了仪器,每次显示尚未显示的新图像时,内存使用量都会增加约 4 MB。 重新显示已经显示的图像时,它会停止增长吗? 是的,它只在最初加载时才会增长。这就是让我困惑的地方。 对于任何想知道的人,我最终所做的是将 uiimages 数组替换为包含图像路径的 nsstrings 数组,然后在我需要它们时加载图像,这样当我在处理完它们后将它们设置为 nil,没有对它们持有任何引用。以上是关于将 uiimage 设置为 nil 不会使用 ARC 释放内存的主要内容,如果未能解决你的问题,请参考以下文章
将 UIImage 添加到数组后,NSMutableArray 返回 nil