Ios 在tableView中重新创建单元格时出现内存警告

Ios 在tableView中重新创建单元格时出现内存警告,ios,Ios,我正在tableview中显示100个远程图像 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //static NSString *CellIdentifier = @"Cell"; NSString *CellIdentifier = [NSString stringWithFormat:@"%d",indexPath.row]

我正在
tableview中显示100个远程图像

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {


//static NSString *CellIdentifier = @"Cell";
NSString *CellIdentifier = [NSString stringWithFormat:@"%d",indexPath.row];

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {

    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

}

cell.imageView.image = nil;
cell.textLabel.text = nil;
cell.detailTextLabel.text = nil;
cell.selectionStyle = UITableViewCellSelectionStyleNone;


// Configure the cell...

for (UIView *view in cell.contentView.subviews) {
    if ([view isKindOfClass:[UIButton class]] || [view isKindOfClass:[UILabel class]]||[view isKindOfClass:[UIImageView class]]) {
        [view removeFromSuperview];
    }
}

int imageNumber = 0;

if (isInSearchMode)
{
    PhotoVO *photoVO = (PhotoVO *)[searchResultArray objectAtIndex:indexPath.row];

    UIImageView *photo_View = [[UIImageView alloc]initWithFrame:CGRectMake(20, 5, width , height - 10)];
    photo_View.tag = 101;
    [[photo_View layer] setBorderWidth:3.0f];
    [[photo_View layer] setBorderColor:[UIColor whiteColor].CGColor];
    [photo_View setImageWithURL:[NSURL URLWithString:photoVO.thumb_URL1] placeholderImage:[UIImage imageNamed:@"loader"]];


    [cell.contentView addSubview:photo_View];

    UILabel *stringLable=[[UILabel alloc]initWithFrame:CGRectMake(130, 20, 150, 30)];
    stringLable.backgroundColor=[UIColor clearColor];
    stringLable.text=photoVO.photoName;
    stringLable.font=[UIFont systemFontOfSize:16.0];
    [cell.contentView addSubview:stringLable];

    UILabel *tagLable=[[UILabel alloc]initWithFrame:CGRectMake(130, 55, 150, 30)];
    tagLable.backgroundColor=[UIColor clearColor];
    tagLable.text=photoVO.tagString;
    tagLable.font=[UIFont systemFontOfSize:12.0];

    [cell.contentView addSubview:tagLable];


}
else
{

    for (int i = (indexPath.row * imagesCount); i < ((indexPath.row *imagesCount) + imagesCount); i++) {

        if (i < [cellImageVOArray count]) { // If resultsArray Count is odd then we no need to create cell image

            PhotoVO *photoVo = (PhotoVO *)[cellImageVOArray objectAtIndex:i];

            UIButton *appIconBtn = [UIButton buttonWithType:UIButtonTypeCustom];

            appIconBtn.frame = CGRectMake(((imageNumber * 5)+5)+(imageNumber * width), 2, width, height -4);

            appIconBtn.tag = i + 100;
            [[appIconBtn layer] setBorderWidth:3.0f];
            [[appIconBtn layer] setBorderColor:[UIColor whiteColor].CGColor];

            [appIconBtn addTarget:self action:@selector(imageTapped:) forControlEvents:UIControlEventTouchUpInside];

            [appIconBtn setBackgroundImageWithURL:[NSURL URLWithString:photoVo.thumb_URL1] placeholderImage:[UIImage imageNamed:@"loader.png"]];

            //[appIconBtn setBackgroundImageWithURL:[NSURL URLWithString:photoVo.thumb_URL1]];

            [cell.contentView addSubview:appIconBtn];
            imageNumber ++;

        }

    }



}

return cell;

}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
//静态NSString*CellIdentifier=@“Cell”;
NSString*CellIdentifier=[NSString stringWithFormat:@“%d”,indexath.row];
UITableViewCell*单元格=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
如果(单元格==nil){
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle重用标识符:CellIdentifier];
}
cell.imageView.image=nil;
cell.textlab.text=nil;
cell.detailTextLabel.text=nil;
cell.selectionStyle=UITableViewCellSelectionStyleNone;
//配置单元格。。。
for(UIView*cell.contentView.subview中的视图){
if([view IsKindof类:[UIButton类]]| |[view IsKindof类:[UILabel类]]| |[view IsKindof类:[UIImageView类]]){
[视图从SuperView移除];
}
}
int imageNumber=0;
如果(IsInSearch模式)
{
PhotoVO*PhotoVO=(PhotoVO*)[searchResultArray对象索引:indexath.row];
UIImageView*photo_View=[[UIImageView alloc]initWithFrame:CGRectMake(20,5,宽度,高度-10)];
photo_View.tag=101;
[[photo_View layer]宽度:3.0f];
[[photo_View layer]setBorderColor:[UIColor whiteColor].CGColor];
[photo_View setImageWithURL:[NSURL URLWithString:photoVO.thumb_URL1]占位符图像:[UIImage ImageName:@“loader”];
[cell.contentView addSubview:photo_View];
UILabel*stringLable=[[UILabel alloc]initWithFrame:CGRectMake(130,20,150,30)];
stringLable.backgroundColor=[UIColor clearColor];
stringLable.text=photoVO.photoName;
stringLable.font=[UIFont systemFontOfSize:16.0];
[cell.contentView addSubview:stringLable];
UILabel*tagLable=[[UILabel alloc]initWithFrame:CGRectMake(130,55,150,30)];
tagLable.backgroundColor=[UIColor clearColor];
tagLable.text=photoVO.tagString;
tagLable.font=[UIFont systemFontOfSize:12.0];
[cell.contentView addSubview:tagLable];
}
其他的
{
对于(int i=(indexPath.row*imagesunt);i<((indexPath.row*imagesunt)+imagesunt);i++){
如果(i<[cellImageVOArray count]){//如果结果数组计数为奇数,则无需创建单元格图像
PhotoVO*PhotoVO=(PhotoVO*)[cellImageVOArray对象索引:i];
UIButton*appIconBtn=[UIButton按钮类型:UIButtonTypeCustom];
appIconBtn.frame=CGRectMake((imageNumber*5)+5)+(imageNumber*width),2,宽度,高度-4);
appIconBtn.tag=i+100;
[[appIconBtn层]宽度:3.0f];
[[appIconBtn layer]setBorderColor:[UIColor WHITECLOR].CGColor];
[appIconBtn addTarget:self action:@selector(imageTapped:)for ControlEvents:UIControlEventTouchUpInside];
[appIconBtn setBackgroundImageWithURL:[NSURL URLWithString:photoVo.thumb_URL1]占位符图像:[UIImage ImageName:@“loader.png”];
//[appIconBtn setBackgroundImageWithURL:[NSURL URLWithString:photoVo.thumb_URL1]];
[cell.contentView addSubview:appIconBtn];
imageNumber++;
}
}
}
返回单元;
}

我使用上面的代码在
tableView
中显示图像,但是我在检查它的所有方式时都会收到内存警告。我认为每次都会创建单元格,因此请告诉我代码中是否存在任何问题。

这是一个问题:
NSString*CellIdentifier=[NSString stringWithFormat:@“%d”,indexPath.row]

您没有重用任何东西,因为您正在为每个单元格创建一个新的标识符。可以重用两种不同的单元格样式,但您只是为每一行创建一个新的单元格

第二,你需要考虑一下你在这里做什么:

for (UIView *view in cell.contentView.subviews) {
    if ([view isKindOfClass:[UIButton class]] || [view isKindOfClass:[UILabel class]]||[view isKindOfClass:[UIImageView class]]) {
        [view removeFromSuperview];
    }
}
每次需要一个单元时,你都要移除构成单元的部分,然后马上重新制作它们。您应该在
UITableView
中尽可能多地重用。您应该考虑创建一个自定义的
UITableViewCell
子类,该子类包含您需要的部分,然后使用它。这就是说,看起来您只有一个图像和两个标签,默认的
UITableViewCell
将具有这些标签,因此您可能根本不需要创建它们,除非您的单元格非常定制

最后,您应该看看您在使用
isInSearchMode
做什么。现在,整个表基本上都有一个if语句。这不是一件可怕的事情,但如果你这样做,你应该有两个单元格标识符,每个可能的单元格一个。然后在
if
语句中,只需交换单元标识符并填写适当的数据

最重要的是,如果可能的话(在您的案例中似乎是这样),您根本不应该使用此方法创建新视图。您应该让
UITableViewCell
来处理这个问题。

创建自定义单元格

您可以从一个简单的子类
UITableViewCell
开始。然后,您可以为需要的每个自定义零件添加特性,如
UILabel
UIImageView
。您可以通过重写
init
来创建它们,也可以将它们放在自定义属性getter中,以便根据需要创建它们

//  CustomCell.h
#import <UIKit/UIKit.h>

@interface Custom : UITableViewCell

@property (strong, nonatomic) UILabel *titleLabel;

@end

//  CustomCell.m
#import "CustomCell.h"

@implementation CustomCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(12.0, 10.0, self.contentView.frame.size.width - 24.0, 22.0)];
        [self.titleLabel setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
        [self.titleLabel setHighlightedTextColor:[UIColor whiteColor]];
        [self.titleLabel setFont:[UIFont boldSystemFontOfSize:17.0]];
        [self.titleLabel setBackgroundColor:[UIColor clearColor]];
        [self.titleLabel setTextColor:[UIColor blackColor]];
        [self.titleLabel setAdjustsFontSizeToFitWidth:YES];
        [self.titleLabel setMinimumFontSize:8.0];

        [self.contentView addSubview:self.titleLabel];
    }
    return self;
}

@end

根据应用程序的工作方式,可以很容易地对其进行进一步重构,但这会让您走上正确的道路。

这是一个问题:
NSString*CellIdentifier=[NSString stringWithFormat:@“%d”,indexath.row]

您没有重用任何东西,因为您正在为每个单元格创建一个新的标识符。可以重用两种不同的单元格样式,但您只是为每一行创建一个新的单元格

第二,你需要考虑一下你在这里做什么:

for (UIView *view in cell.contentView.subviews) {
    if ([view isKindOfClass:[UIButton class]] || [view isKindOfClass:[UILabel class]]||[view isKindOfClass:[UIImageView class]]) {
        [view removeFromSuperview];
    }
}
每次需要一个单元时,你都要移除构成单元的部分,然后马上重新制作它们。你应该尽可能地重复使用
NSString *CellIdentifier = [NSString stringWithFormat:@"%d",indexPath.row];
NSString *CellIdentifier = @"CellId";