【问题标题】:App crash due to Memory Issue in ios sdk由于 ios sdk 中的内存问题导致应用程序崩溃
【发布时间】:2013-05-24 20:10:58
【问题描述】:

在我的应用程序中,我加载了带有图像的表格视图。有一个删除按钮可以删除图片。

当图像太大(例如 1.5MB)时,应用程序由于内存不足警告而崩溃。

我如何使用仪器或其他解决方案来解决这个问题?

如何在cellforRowIndexPath方法中释放对象。

我应该让项目启用 ARC 吗?

我是做 ARC Enabled 的项目,那会有什么效果?

我的 cellRow 代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    }

    for (UIView *v in [cell.contentView subviews]) {
        [v removeFromSuperview];
    }

    int section = indexPath.section;

    sectionItems = [sections objectAtIndex:section];

    int n = [sectionItems count];

    //NSLog(@"section items -%d",n );

    int  i=0;
    int i1=0;

    while(i<n)
    {
        int yy = 3 +i1*100;
        int j=0;
        for(j=0; j<3;j++){

            if (i>=n) break;
            Item *item = [sectionItems objectAtIndex:i];            

            //Imageview
            UIImageView *pp=[[UIImageView alloc]initWithFrame:CGRectMake(20+215*j, yy*2.3, 190, 190)];
            pp.image=item.img;
            //NSLog(@"%@ %@",item.img,item.image);
            //pp.backgroundColor=[UIColor redColor];
            [cell.contentView addSubview:pp];

            //Image Button
           // CGRect rect1 = CGRectMake(30+215*j, yy*2.3, 190, 250);
            CGRect rect1 = CGRectMake(20+215*j, yy*2.3, 190, 190);
            UIButton *button1=[[UIButton alloc] initWithFrame:rect1];
            [button1 setFrame:rect1];
            NSString *tagValue1 = [NSString stringWithFormat:@"%d%d", indexPath.section+1, i];
            button1.tag = [tagValue1 intValue];
            [button1 setBackgroundImage:nil forState:UIControlStateNormal];
            [button1 addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
           // button1.backgroundColor=[UIColor greenColor];
            [cell.contentView addSubview:button1];

           //delete button..16 03 2013
            CGRect rect2 = CGRectMake(176+215*j, yy*2.3, 30, 30);
            UIButton *button2=[[UIButton alloc] initWithFrame:rect2];
            [button2 setFrame:rect2];
            NSString *tagValue2 = [NSString stringWithFormat:@"%d%d", indexPath.section+1, i];
            button2.tag = [tagValue2 intValue];
            [button2 setBackgroundImage:[UIImage imageNamed:@"can.png"] forState:UIControlStateNormal];
            [button2 addTarget:self action:@selector(deleteItem:) forControlEvents:UIControlEventTouchUpInside];
            //button2.backgroundColor=[UIColor blackColor];


            [cell.contentView addSubview:button2];
            if (isDeleting == YES)
            {
                [button2 setHidden:NO];
                [button1 setUserInteractionEnabled:NO];
            }
            else
            {
                [button1 setUserInteractionEnabled:YES];
                [button2 setHidden:YES];
            }


            i++;
        }
        i1 = i1+1;
    }

    cell.selectionStyle=UITableViewCellSelectionStyleNone;

    return cell;
}

【问题讨论】:

  • 发布你的 cellforRowIndexPath 代码
  • 确保您的代码没有泄漏内存。例如:表格视图单元正在泄漏内存。使用if (cell == nil) { cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; }。同样检查其他此类泄漏,解决它们。同样使用 ARC 也无济于事,因为它不是垃圾收集,应用程序内存占用仍需要由开发人员处理。
  • 这里的操作系统没有泄漏。请修正标题
  • 一张图像在磁盘上的大小为 1.5MB 并不意味着它在内存中就那么大。图像未压缩到内存中,并且可以比磁盘上的压缩版本大很多倍。您通常会在内存中查看每个像素大约 4 个字节的图像。
  • @BradLarson,我应该怎么做才能解决这个问题?

标签: iphone ios objective-c xcode memory


【解决方案1】:

嗯……嗯,首先:

pp 
button1
button2

已分配且从未释放... 在您将它们添加为 subView 之后,开始为它们添加一个版本:

[pp release];
[button1 release];
[button2 release];

每次用户滚动时,您当前的代码都会分配大量内存,并且永远不会释放... 这可能会解决您的问题...

更进一步应该重用对象,学习如何重用所有按钮和 imageView(只需为它们设置新内容,作为图像,而不是删除它们并重新创建它们;我知道单元格可能有不同数量的按钮。 .. 但我相信你可以管理它.. 删除数量过多的对象,这可能会更好)

【讨论】:

    【解决方案2】:

    代替

    for (UIView *v in [cell.contentView subviews]) {
            [v removeFromSuperview];
        }
    

    试试这个

    [[cell.contentView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
    

    我认为您的编码是在 UIView *v 中复制视图并从 v 中删除 superView 而不是 [cell.contentView subViews]

    【讨论】:

      猜你喜欢
      • 2012-06-19
      • 1970-01-01
      • 2011-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-09
      • 2013-06-15
      • 1970-01-01
      相关资源
      最近更新 更多