在ViewController中接收内存警告(“页面​​滑动样式ScrollView”)

时间:2013-08-06 11:51:38

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

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

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

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

现在问题是我无法释放我不知道的内存分配,因为根据我的代码,分配的所有东西都是释放。我也尝试过工具,但这不起作用。

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

请确保您没有回答有关器乐泄漏的建议,因为这没有帮助。我需要知道如何释放未使用的内存。

您可以看到单个视图中有三个视图,这是一个滚动条,因此当您滚动浏览时,将显示更多视图,顶部还有一个图像,也是一个滚动条。除此之外,还有一个显示细节的桌面视图。但是当我创建这个视图时,我面临着内存问题,所以我正在从这个视图中释放所有内容,即使我试图在导航时删除整个视图。为此,我使用了“PagedFlowView”示例

https://github.com/kejinlu/PagedFlowView

以上链接适用于pagedflowview示例,以下链接适用于我已实现的代码引用类请查看我的课程,并告诉我在哪里可以改进它。

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

6 个答案:

答案 0 :(得分:0)

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

  1. 考虑对UITableViewCell使用autorelease:

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

    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
        cell = [self tableViewCellWithReuseIdentifier:CellIdentifier];
    
  3. 第二部分要求您分配和处理'标识符'(用于标识单元格的字符串)。

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

答案 1 :(得分:0)

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

width x height x n bytes其中n是表示每个像素颜色的位数,大多数是4。

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

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

答案 2 :(得分:0)

我刚看了一下PagedFlowView项目。实际上我虽然错误地重用了你正在创建的UIImageView,但是让内存增加​​了。但似乎做得很好。 我尝试了一个自动释放池(仅使用提供的.tiff文件在PagedFlowView上)并且似乎减少了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 :(得分:0)

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

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

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

答案 4 :(得分:0)

首先 - 检查你的dealloc,似乎你至少泄漏了音乐库(可能还有很多)。 第二 - 修改你的

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

在您当前的代码中:

如果view是nil:你正在创建自动释放池但是没有耗尽它(并且最好使用@autoreleasepool指令),然后你正在泄漏scrollview(alloc / init,然后添加子视图,但看不到任何版本) ,然后指向图像的指针设置为nil,然后你试图释放它(消息为nil是no-op,同样是上面的imageview),等等。这部分充满了泄漏,因为它似乎来自代码。

如果视图不是零: 您正在为此已配置的视图添加新的scrollview等(并将其泄漏)。因此,您只需重新创建它们,而不仅仅是重新配置这些视图。

我建议你为这些视图制作UIView的子类,制作像

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

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

此外 - 此代码需要进行大量重构。它很难维护,改变或改进。

答案 5 :(得分:0)

查看您的代码我发现的是您正在分配imageview&每次都在单元格上查看webview。你可以通过添加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];