【问题标题】:Receiving memory warning in ViewController ("Page swipe Style ScrollView")在 ViewController 中接收内存警告(“Page swipe Style ScrollView”)
【发布时间】:2013-08-07 09:56:59
【问题描述】:

我有一个项目,其中有两个视图,在第一个视图中我显示了一个 uitableview。并在选择任何行单元格时打开另一个视图。

第一个视图有 10 个单元格,每个单元格在被选中时会打开其他视图,其中包含最多 21 个视图和最少 1 个视图。

第二个视图中的每个视图都由图像数组 tableview 和 tableview 中的许多子视图组成(图像数组也显示在具有多个图像视图的滚动视图中)

现在的问题是我无法释放我不知道的内存分配,因为根据我的代码分配的所有内容都是释放。我也试过乐器,但没用。

以前,当我只访问一个视图时,它会使应用程序崩溃,因此我降低了图像的分辨率,现在它在没有其他应用程序打开时导航近 9 个应用程序,否则它适用于 6 个视图。现在我什至不能降低图像的分辨率,因为现在质量已经降低了。那么如何减少这种根本不支持我的应用程序甚至释放占用的内存的内存分配。

请确保您不要回复诸如仪器泄漏之类的建议,因为这没有帮助。我需要知道如何释放未使用的内存。

您可以看到一个视图中有三个视图,这是一个滚动条,因此当您通过滚动进行导航时会显示更多视图,并且顶部有一个图像,也是一个滚动条。除此之外,还有一个显示详细信息的表格视图。但是当我创建这个视图时,我遇到了内存问题,因此我要从这个视图中释放所有内容,即使我试图在返回时删除整个视图。为此,我使用了“PagedFlowView”示例

https://github.com/kejinlu/PagedFlowView

上面的链接是 pagedflowview 示例,下面的链接是我实现的代码参考类,请检查我的类,让我知道我可以在哪里改进它。

http://www.4shared.com/file/rHmRDr2E/SwipeExerciseViewController.html

【问题讨论】:

  • 如果您能通过点击旁边的灰色复选标记来接受您的问题的正确答案,那就太好了。
  • 如果这些对我没有用,我为什么要接受答案。我自己找到了答案。
  • 如果您找到了解决方案并将其标记为正确答案,即使这是您自己发布的问题,您也可以随时提交答案。这样其他面临同样问题的人就会知道这个问题的解决方案。

标签: iphone ios ipad memory-management memory-leaks


【解决方案1】:

在处理图像时,请记住另外一件事。当您使用图像时,它不会像许多人所期望的那样占用它所显示的文件大小(即,对于 2048 x 1536 小于 3MB 的东西)。相反,它实际上是以原始格式加载的,基于如下计算占用内存:

宽 x 高 x n 字节,其中 n 是用于表示每个像素颜色的位数,通常为 4。

所以对于相同的 2048 x 1536 图像,它将占用 12MB。

所以现在检查你正在谈论的图像的原始分辨率是多少,并计算它需要多少 MB,并根据它更改你的代码。

【讨论】:

  • 是的,以前它的尺寸有点大,但我已经裁剪了图像并降低了图像的分辨率。现在图像以 KB 为单位,分辨率更便宜。
【解决方案2】:

我刚刚快速浏览了 PagedFlowView 项目。实际上我虽然它错误地重用了你正在创建的 UIImageView,让内存增加​​。但似乎做得很好。 我尝试使用自动释放池(仅在 PagedFlowView 上使用提供的 .tiff 文件),似乎减少了 20% 的分配字节数。

在 PagedFlowView.m 文件的第 85 行中,您应该找到方法 removeCellAtIndex:(NSInteger)index

尝试以这种方式编辑它:

- (void)removeCellAtIndex:(NSInteger)index{
  UIView *cell = [_cells objectAtIndex:index];
  if ((NSObject *)cell == [NSNull null]) {
      return;
  }

  @autoreleasepool {

    [self queueReusableCell:cell];

    if (cell.superview) {
        cell.layer.transform = CATransform3DIdentity;
        [cell removeFromSuperview];
    }

    [_cells replaceObjectAtIndex:index withObject:[NSNull null]];
  }
}

这应该会有所帮助。但也许还不够。如果您仍然有问题,我可以更深入地了解 PagedFlowView 如何使用 _cells 和 _reusableCells。

【讨论】:

    【解决方案3】:

    添加 100 个空视图也不会导致内存问题,但添加 10 个图像会导致内存问题。重新考虑如何呈现数据的过程。

    我可以建议的一种方法是减小您在第二个视图中显示的缩略图的大小,您说那里会有 1 到 21 个视图。然后引入多余的步骤,例如单击该缩略图以进入具有原始分辨率图像的详细屏幕。

    第二种方法,我能想到的是有一个占位符图像。异步只下载可见单元格的图片并写入Cache目录,然后继续显示只有可见单元格的图片

    【讨论】:

      【解决方案4】:

      首先 - 检查您的 dealloc,似乎您至少泄漏了音乐库(并且可能更多)。 第二次 - 修改你的

      - (UIView *)flowView:(PagedFlowView *)flowView cellForPageAtIndex:(NSInteger)index
      

      在您当前的代码中:

      如果视图为零:您正在创建自动释放池但没有耗尽它(最好使用@autoreleasepool 指令),那么您正在泄漏滚动视图(alloc/init,然后添加子视图,但看不到任何释放) ,然后指向图像的指针设置为 nil,然后您尝试释放它(到 nil 的消息是无操作的,上面的 imageview 也是如此)等。这部分充满了从代码中看起来的泄漏。

      如果视图不为零: 您正在向这个已配置的视图添加新的滚动视图等(并且也会泄漏它们)。因此,您几乎是在重新创建它们,而不是仅仅重新配置这些视图。

      我建议你为这些视图创建 UIView 的子类,创建一个像

      这样的公共方法
      - (void)configureWithParameters:(NSDictionary *)parameters;
      - (id)initWithParameters:(NSDictionary *)parameters;
      

      在该类中,当 flowview 请求查看时,首先尝试使可重用单元出列,如果它是 nil - alloc/init/autorelease 这个带有所需参数的视图,如果视图已经创建 - 使用配置方法。

      另外 - 此代码需要大量重构。这将很难维护、更改或改进。

      【讨论】:

        【解决方案5】:

        查看您的代码后,我发现您每次都在单元格上分配 imageview 和 webview。当单元格为 nil 时,您可以通过添加 imageview 和 webview 来减少这部分。如您所知,单元格被重复使用,我们可以避免一些内存警告。

        这是修改后的代码:

        static NSString *store=@"cell";
            UITableViewCell *utvc = [[tableView dequeueReusableCellWithIdentifier:store] autorelease];
            if(utvc == nil)
            {
                utvc = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
        
        UIImageView *textView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 40, 276, 360)];
                textView.tag = 1001;  // some tag value
                [textView setImage:[UIImage imageNamed:@"bluelineBg.png"]];
                [utvc addSubview:textView];
                [textview release];
        
             UIWebView *webv = [[UIWebView alloc]initWithFrame:CGRectMake(0, -12, 277, 300)];
                webv.userInteractionEnabled = FALSE;
                webv.scrollView.scrollEnabled = FALSE;
                webv.tag = 1002;//some tag value
                [webv setBackgroundColor:[UIColor clearColor]];
                [webv setOpaque:NO];
                [utvc addSubview:webv];
                [webv releae];
        
        
            }
          UIImageView *imageview = [cell viewWithTag:1001];
        
        [imageview setImage:[UIImage imageNamed:@"bluelineBg.png"]];
        
        UIWebView *webView = [cell viewWithTag:1002];
        
        [webView loadHTMLString:[NSString stringWithFormat:@"<html><body style='font-family:Helvetica; font-size:14px;background-color: transparent; '><head><style> OL{ color: #555555 } </style></head><br><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mudra</b> : Prayer Pose<br><br><ol style=\"color:color: #999999;\"><li>Sit comfortably in easy pose with the legs crossed</li><li>Bring the palms together at the center of the chest</li><li>Inhale deeply</li><li>Chant 'Sat Nam' three times or chant the 'Long Time Sunshine' song to finish<br><br><i>Time per repetition : 15 Sec.</i></li></ol></body></html>"] baseURL:Nil];
        

        【讨论】:

          【解决方案6】:

          我最近遇到了 UITableView 的问题,在我的情况下,这是错误的 UITableViewCell 的创建。其实至少有两点要检查:

          1. 考虑为 UITableViewCell 使用自动释放:

            UITableViewCell * cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
            
          2. 最佳实践希望您通过使用 [tableView dequeueReusableCellWithIdentifier] 来重用 UITableViewCell 实例(请参阅下面的示例,取自 cellForRowAtIndexPath)

            UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
            if (cell == nil)
                cell = [self tableViewCellWithReuseIdentifier:CellIdentifier];
            

          第二部分,要求您分配和处理一个“标识符”(用于识别单元格的字符串)。

          如果您仍有疑问,请考虑发布您的代码。 问候, D.

          【讨论】:

          • 是的,它没有帮助,因为我已经自动释放 tableview 以及 tableview 单元格。感谢您的回复
          • 我一直在看PagedFlowView的源代码。这是导致内存泄漏的观点吗?我看到它使用数组来保持对 UITableViewCells 的强引用。您是否检查过单元格是否已从阵列中正确删除?如果你能确认示例项目有同样的问题,我今晚会调试它;)
          • 是的,如果你检查一下它真的会很有帮助,首先创建包含 21 个视图的整个视图,其中包含高分辨率图像和表格视图,包括 textview 标签 blabla...你会知道泄漏问题。是的,请提出有人可能有兴趣查看的问题
          • dna2 检查我在问题中附加的链接,您会找到附加的 .m 文件供您参考
          猜你喜欢
          • 2015-12-24
          • 2011-04-30
          • 1970-01-01
          • 1970-01-01
          • 2013-10-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多