Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 自定义UITableviewCell放弃内存问题_Ios_Iphone_Objective C_Uitableview_Instruments - Fatal编程技术网

Ios 自定义UITableviewCell放弃内存问题

Ios 自定义UITableviewCell放弃内存问题,ios,iphone,objective-c,uitableview,instruments,Ios,Iphone,Objective C,Uitableview,Instruments,目前,我正在尝试使用来自仪器的数据优化我的iOS应用程序。我注意到我的一个UITableViewCell出现问题,如果点击上面的单元格,我将插入或删除该单元格。问题是,我的细胞似乎没有在cellForRowAtIndexPath中循环使用,而是创建了一个全新的细胞,在此之前创建的细胞被丢弃并留在内存中。这导致了一个主要问题,因为每个单元的成本约为2mb,因此很容易使用大量内存,只需打开和关闭单元即可超过100mb。下图对此进行了说明 我的自定义UITableViewCell包含 UIScrol

目前,我正在尝试使用来自仪器的数据优化我的iOS应用程序。我注意到我的一个UITableViewCell出现问题,如果点击上面的单元格,我将插入或删除该单元格。问题是,我的细胞似乎没有在cellForRowAtIndexPath中循环使用,而是创建了一个全新的细胞,在此之前创建的细胞被丢弃并留在内存中。这导致了一个主要问题,因为每个单元的成本约为2mb,因此很容易使用大量内存,只需打开和关闭单元即可超过100mb。下图对此进行了说明

我的自定义UITableViewCell包含

  • UIScrollView
    • 自定义
      ui视图
      (图形视图)
  • 自定义
    ui视图
    (轴视图)
其他一些信息

  • 使用带有
    UIScrollView
    和其他控件的原型单元格(代码中未显示)
  • GraphicView子类uiview并使用drawRect绘制图形
我不确定我是否使用了正确的方法,因为用户通常一次只能在屏幕上显示一个单元格。我的问题是我的代码出了什么问题,为什么我使用了这么多内存,如何修复

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if([self.prices[indexPath.row] isEqual:@(1)])
    {
        static NSString *CellIdentifier = @"statCell";
        PTPriceStatCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        int width = kOffsetX + dateRangeInDays * kStepX + kOffsetX;
        float axisWidth = //Some calculataion;

        cell.scrollView.frame = CGRectMake(0,0,cell.frame.size.width - axisWidth, 128);

       GraphView *graphView = [[GraphView alloc]initWithFrame:CGRectMake(axisWidth, 0, width , cell.scrollView.frame.size.height)];

        graphView.range = dateRangeInDays;
        graphView.xValues= xAxis;
        graphView.yValues = yAxis;
        graphView.earliestDate = earliestDate;


        [cell.scrollView addSubview:graphView];

        CGPoint bottomOffset = CGPointMake( cell.scrollView.contentSize.width - cell.scrollView.bounds.size.width,0);
        [cell.scrollView setContentOffset:bottomOffset animated:NO];
        YAxis *axisView = [[YAxis alloc]initWithFrame:CGRectMake(0, cell.scrollView.frame.origin.y, axisWidth, cell.scrollView.frame.size.height)];

        axisView.yValues = yAxis;
        [cell.contentView addSubview:axisView];
        cell.scrollView.contentSize = CGSizeMake(cell.scrollView.graphView.frame.size.width + axisWidth, cell.scrollView.graphView.frame.size.height);

        return cell;
    }
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath     *)indexPath
{
    if (range < [self.prices count] && [[self.prices objectAtIndex:range] isEqual:@(1)])
    {
          [self.prices removeObjectAtIndex:range];
          [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 
     }
     else
     {
         Price *currentPrice = self.prices[[self getPricePositionFor:(int)indexPath.row]][0];
         if (currentPrice.value != nil) 
         {
             [self.prices insertObject:@(1) atIndex:range];
             [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
         }
     }
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
如果([self.prices[indexath.row]isEqual:@(1)])
{
静态NSString*CellIdentifier=@“statCell”;
PTPriceStatCell*单元格=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
int width=kOffsetX+dateRangeInDays*kStepX+kOffsetX;
float axisWidth=//一些计算;
cell.scrollView.frame=CGRectMake(0,0,cell.frame.size.width-axisWidth,128);
GraphView*GraphView=[[GraphView alloc]initWithFrame:CGRectMake(axisWidth,0,width,cell.scrollView.frame.size.height)];
graphView.range=日期范围天数;
graphView.xValues=xAxis;
graphView.yValues=yAxis;
graphView.earliestDate=earliestDate;
[cell.scrollView addSubview:graphView];
CGPoint bottomOffset=CGPointMake(cell.scrollView.contentSize.width-cell.scrollView.bounds.size.width,0);
[cell.scrollView setContentOffset:bottomOffset动画:否];
YAxis*axisView=[[YAxis alloc]initWithFrame:CGRectMake(0,cell.scrollView.frame.origin.y,axisWidth,cell.scrollView.frame.size.height)];
axisView.yValues=yAxis;
[cell.contentView addSubview:axisView];
cell.scrollView.contentSize=CGSizeMake(cell.scrollView.graphView.frame.size.width+axisWidth,cell.scrollView.graphView.frame.size.height);
返回单元;
}
}
-(void)tableView:(UITableView*)tableView未选择RowatineXpath:(NSIndexPath*)indexPath
{
如果(范围<[self.prices count]&&[self.prices objectAtIndex:range]相等:@(1)])
{
[self.prices removeObjectAtIndex:range];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]with RowAnimation:UITableViewRowAnimationAutomatic];
}
其他的
{
Price*currentPrice=self.prices[[self-getPricePositionFor:(int)indexPath.row][0];
如果(currentPrice.value!=零)
{
[self.pricesinsertobject:@(1)atIndex:range];
[self.tableView insertRowsAtIndexPaths:[NSArray arraywhithobject:newIndexPath]with rownanimation:uitableview rownanimationautomatic];
}
}
}

您正在将可重用单元出列,但要继续向它们添加
graphview
axisview
。由于它们从未从细胞中移除,因此它们正在累积

如果您a)检查单元格上是否已经存在这些视图并重新配置它们,或者b)在
PTPriceStatCell
上实现
-prepareForReuse
,并清理单元格中的子视图,则问题应该消失

最小清理示例:

NSArray *oldGraphs = [cell.scrollView.subviews filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id subview, NSDictionary *bindings) {
    return [subview isKindOfClass:[GraphView class]];
}]];
[oldGraphs makeObjectsPerformSelector:@selector(removeFromSuperview)];

让GraphView和AxisView作为PTPriceStatCell的属性。并使用cell.graphView或cell.axisView进行访问。您的代码每次都在实例化它们,而且从未发布过。

如果(…)这个条件是什么?我认为你没有在问题中发布正确的代码。你在重复使用你的单元格。但问题在于“graphView”和“axisView”。检查单元格中是否存在这些视图,然后跳过该部分代码。希望能有所帮助。我以前尝试过此解决方案,但没有解决问题。谢谢你的回答。非常感谢,这个解决方案奏效了!我不知道这个方法存在。我非常感激,昨晚我一直到凌晨4点都在试图找到一个解决方案,但没有结果。我现在终于可以发布这个应用程序,并获得一些急需的睡眠。再次感谢你。