8

我很抱歉,因为这可能是一个愚蠢和菜鸟的问题......

我正在使用SDWebImage在我的cellForRowAtIndexPath方法中的UITableView中显示图片,使用经典

[cell.pointPicture setImageWithURL:[NSURL URLWithString:thePoint.imageURL] placeholderImage:[UIImage imageNamed:POINT_DEFAULT_IMAGE]];

(显示的图片是轻巧且压缩良好的 jpg,只是一些 ko,是的,我当然使用的是 dequeueReusableCellWithIdentifier)。

当我使用“ Instrument - Allocations ”检查我的应用程序并向下滚动我的 UITableView(包含图片的 40 个单元格,有点像 Instagram)时,我使用了大量内存!(见截图)

仪器分配截图

但它似乎是“ VM ”,尤其是来自 coreGraphics 库的“ VM:CG raster data ”。

所以问题是:

  • 正常吗?
  • 这是一个严重的问题吗?
  • 有没有办法避免这种情况?

很抱歉,在网上搜索了几下后,我找不到任何有关“ VM:CG 栅格数据”的相关信息......知道吗?提前致谢 !

4

4 回答 4

4

我遇到了同样的问题并找到了根本原因,至少在我的实现中是这样。

根本原因

根本原因是我的表格单元格存储了一个指向存储在SDWebImage缓存中的图像的指针。这个指针,导致SDWebImage的内存释放函数在收到 iOS 的内存警告时没有释放任何内存。 removeAllObjects

解决方案 1 - 保留weakViewController 中的指针,并仅允许 SDWebImage 保留指向所有UIImage对象的强指针。

解决方案 2 - 实施- (void)prepareForReuse并将图像指针设置为nil

要测试此解决方案,请运行您的应用程序并模拟内存警告 - 您将能够看到已删除的数据

于 2014-02-01T09:37:42.277 回答
0

正如从事 SDWebImage 工作的人向我解释的那样:

SDWebImage缓存图像正在使用NSCache. 它是可丢弃的内存。请参阅Apple 文档,因此这是完全正常的行为,如果需要,内存会被释放。

于 2013-10-28T19:19:55.087 回答
0

我遇到过同样的问题。我的问题似乎源于SDWebImage缓存以外的其他东西,但由于它确实有助于内存积累,我认为的第一件事是缓存可能是我的问题的原因。但事实并非如此。可能是你有同样的问题。请记住,我正在使用 ARC。

  • 使用模板运行分析器Leaks并检查您自己的类在Allocation Summary.
  • 深入研究它们并检查它们是如何分配的,如果有泄漏。Leaks请注意,由于您使用的是 ARC,因此仪器中不会出现泄漏。因此 Instruments 可以认为一切正常,但仍有可能在某处发生泄漏。通过深入研究您自己的课程分配,您可以找出问题所在。
  • 请记住,保留/释放计数信息仅在使用Leaks模板时提供,而不是在使用Allocations模板时提供。

我的问题是我直接从块内引用实例变量和 self 而没有将它们重新分配给__weak变量。当 self 在块中使用时,它会自动被 ARC 保留,有时永远不会释放。弱引用可以防止这种情况发生。

例如,这是错误的:

[[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardDidShowNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
    [self.view setContentOffset:CGPointMake(0.0, kKeyboardOffset) animated:YES];
}];

__weak您应该使用这样的引用调用 self :

__weak YourViewControllerClass *weakSelf = self;
[[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardDidShowNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
    [weakSelf.view setContentOffset:CGPointMake(0.0, kKeyboardOffset) animated:YES];
}];

由于我的应用程序使用了很多块,因此Leaks仪器无法检测到大量泄漏。当我修复它们时,内存问题就消失了。

我希望这有帮助。

于 2014-02-04T14:44:59.897 回答
0

尽管NSCache在低内存系统通知上释放内存也更关键(并且内存占用更小)对象将在程序的其他部分被丢弃。

最好将库的maxMemoryCost(设置NSCache totalCostLimit)设置为限制以防止 SDWebImage 触发内存通知。

于 2014-06-30T01:49:58.240 回答