VM:UITableViewLabel 耗尽内存 iOS
VM: UITableViewLabel eating up memory iOS
当我滚动 UITableView 时,内存不断增加,当我 运行 "Allocations".
时,我得到了这种结果
我看到他们的 VM:UITableViewLabel 内存不断增加并且是持久的,他们有什么办法可以消除这种不断增加的内存
-(UITableViewCell*) tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
NSString *text = @"";
BOOL defaultStyle = YES;
static NSString *CellIdentifier = @"Cell";
UITableViewCell *defaultCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (defaultCell == nil) {
defaultCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
else{
NSLog(@"reusing the cell");
}
defaultCell.textLabel.textAlignment = NSTextAlignmentLeft;
defaultCell.userInteractionEnabled = YES;
defaultCell.textLabel.font = [UIFont systemFontOfSize:26.0f];
UIImageView *iv = defaultCell.imageView;
int totalSections = [self numberOfSectionsInTableView:tableView];
NSInteger computedSection = indexPath.section;
if (defaultStyle)
{
defaultCell.selectionStyle = UITableViewCellSelectionStyleBlue;
defaultCell.backgroundColor = [UIColor whiteColor];
defaultCell.textLabel.textColor = [UIColor blackColor];
}
else if (computedSection == 0)
{
const int totalRows = [self tableView:self.tableView numberOfRowsInSection:indexPath.section];
if (indexPath.row == 0) {
text = @"Style1";
defaultStyle = NO;
if (self.style1 == nil)
{
defaultCell.selectionStyle = UITableViewCellSelectionStyleNone;
defaultCell.textLabel.textColor = [UIColor grayColor];
}
else
{
defaultCell.selectionStyle = UITableViewCellSelectionStyleBlue;
defaultCell.textLabel.textColor = [UIColor blackColor];
}
iv.image = [UIImage imageNamed: @"Style1.png"];
}
if(indexPath.row == totalRows - 2){
// Categories
text = @"Style2";
iv.image = [UIImage imageNamed: @"Style2.png"];
defaultStyle = NO;
if ( self.style2 == nil) {
defaultCell.selectionStyle = UITableViewCellSelectionStyleNone;
defaultCell.textLabel.textColor = [UIColor grayColor];
} else {
defaultCell.selectionStyle = UITableViewCellSelectionStyleBlue;
defaultCell.textLabel.textColor = [UIColor blackColor];
}
}
else if (indexPath.row == totalRows - 1){
// Search
text = @"Style3";
iv.image = [UIImage imageNamed: @"Style3.png"];
}
}
else if (computedSection == 1)
{
MyCustomTableViewCell *cell = [mTableView dequeueReusableCellWithIdentifier:kCustomTableCellIdentifier];
if ( cell == nil ) {
cell = [CustomTableViewCell loadFromNibNamed:@"CustomTableViewCell"];
}
cell.titleLabel = @"custom cell";
cell.openImage =[UIImage imageNamed: @"custom.png"]
return cell;
}
else if (indexPath.section == totalSections - 1)
{
if (indexPath.row == 0)
{
text = @"Account";
defaultStyle = NO;
if (self.hasAccount == nil)
{
defaultCell.selectionStyle = UITableViewCellSelectionStyleNone;
defaultCell.textLabel.textColor = [UIColor grayColor];
}
else
{
defaultCell.selectionStyle = UITableViewCellSelectionStyleBlue;
defaultCell.textLabel.textColor = [UIColor whiteColor];
}
iv.image = [UIImage imageNamed: @"Account.png"];
}
}
defaultCell.textLabel.text = text;
return defaultCell;
}
我认为您没有重复使用 table 视图中使用的单元格
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"myCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"myCell"];
} else {
// reset your cell values here
}
在你的 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
中使用它
我已经将你的代码复制到一个新项目中,并做了一些测试。它从未在真实设备上使用超过 10 Mb 的内存,因此可能有 2 种情况。
调用一个泄漏的方法。此时你只调用了 cellForRow 中的一个方法,因为:BOOL defaultStyle = YES;
这个方法是:
int totalSections = [self numberOfSectionsInTableView:tableView];
请问你post也可以用这个方法吗?
UITableViewCell 子类在重用时泄漏。现在这不是一个选项,因为您正在使用 UITableViewCell。
注意事项 #1:如果项目在 ARC 中,请删除自动释放。
小记#2:使用
static NSString *CellIdentifier = @"Cell";
UITableViewCell *defaultCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
而不是:
static NSString *CellIdentifier = @"Cell";
UITableViewCell *defaultCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (defaultCell == nil) {
defaultCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
else{
NSLog(@"reusing the cell");
}
而且您不需要手动检查和分配新单元格。
感谢大家的帮助,以下解决方案对我有用
1.
-(void) viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kDefaultCellIdentifier];
[self.tableView registerNib:[UINib nibWithNibName:@"CustomTableViewCell" bundle:nil] forCellReuseIdentifier:kCustomTableCellIdentifier];
}
如@Péter Kovács 所述
2.
两个单元格都使用了 indexPath 方法
static NSString *CellIdentifier = kDefaultCellIdentifier;
UITableViewCell *defaultCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
static NSString *CellIdentifier = kCustomTableViewCellIdentifer;
UITableViewCell *defaultCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
3。
主要问题我在全局使用 defaultCell ,它也为 CustomTableViewCell 使 defaultCell 出队,因此在触发 CustomTableViewCell 块的情况下,它使两个单元格出队。根据行对相应的单元格进行出列解决了这个问题。
当我滚动 UITableView 时,内存不断增加,当我 运行 "Allocations".
时,我得到了这种结果-(UITableViewCell*) tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
NSString *text = @"";
BOOL defaultStyle = YES;
static NSString *CellIdentifier = @"Cell";
UITableViewCell *defaultCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (defaultCell == nil) {
defaultCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
else{
NSLog(@"reusing the cell");
}
defaultCell.textLabel.textAlignment = NSTextAlignmentLeft;
defaultCell.userInteractionEnabled = YES;
defaultCell.textLabel.font = [UIFont systemFontOfSize:26.0f];
UIImageView *iv = defaultCell.imageView;
int totalSections = [self numberOfSectionsInTableView:tableView];
NSInteger computedSection = indexPath.section;
if (defaultStyle)
{
defaultCell.selectionStyle = UITableViewCellSelectionStyleBlue;
defaultCell.backgroundColor = [UIColor whiteColor];
defaultCell.textLabel.textColor = [UIColor blackColor];
}
else if (computedSection == 0)
{
const int totalRows = [self tableView:self.tableView numberOfRowsInSection:indexPath.section];
if (indexPath.row == 0) {
text = @"Style1";
defaultStyle = NO;
if (self.style1 == nil)
{
defaultCell.selectionStyle = UITableViewCellSelectionStyleNone;
defaultCell.textLabel.textColor = [UIColor grayColor];
}
else
{
defaultCell.selectionStyle = UITableViewCellSelectionStyleBlue;
defaultCell.textLabel.textColor = [UIColor blackColor];
}
iv.image = [UIImage imageNamed: @"Style1.png"];
}
if(indexPath.row == totalRows - 2){
// Categories
text = @"Style2";
iv.image = [UIImage imageNamed: @"Style2.png"];
defaultStyle = NO;
if ( self.style2 == nil) {
defaultCell.selectionStyle = UITableViewCellSelectionStyleNone;
defaultCell.textLabel.textColor = [UIColor grayColor];
} else {
defaultCell.selectionStyle = UITableViewCellSelectionStyleBlue;
defaultCell.textLabel.textColor = [UIColor blackColor];
}
}
else if (indexPath.row == totalRows - 1){
// Search
text = @"Style3";
iv.image = [UIImage imageNamed: @"Style3.png"];
}
}
else if (computedSection == 1)
{
MyCustomTableViewCell *cell = [mTableView dequeueReusableCellWithIdentifier:kCustomTableCellIdentifier];
if ( cell == nil ) {
cell = [CustomTableViewCell loadFromNibNamed:@"CustomTableViewCell"];
}
cell.titleLabel = @"custom cell";
cell.openImage =[UIImage imageNamed: @"custom.png"]
return cell;
}
else if (indexPath.section == totalSections - 1)
{
if (indexPath.row == 0)
{
text = @"Account";
defaultStyle = NO;
if (self.hasAccount == nil)
{
defaultCell.selectionStyle = UITableViewCellSelectionStyleNone;
defaultCell.textLabel.textColor = [UIColor grayColor];
}
else
{
defaultCell.selectionStyle = UITableViewCellSelectionStyleBlue;
defaultCell.textLabel.textColor = [UIColor whiteColor];
}
iv.image = [UIImage imageNamed: @"Account.png"];
}
}
defaultCell.textLabel.text = text;
return defaultCell;
}
我认为您没有重复使用 table 视图中使用的单元格
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"myCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"myCell"];
} else {
// reset your cell values here
}
在你的 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
我已经将你的代码复制到一个新项目中,并做了一些测试。它从未在真实设备上使用超过 10 Mb 的内存,因此可能有 2 种情况。
调用一个泄漏的方法。此时你只调用了 cellForRow 中的一个方法,因为:
BOOL defaultStyle = YES;
这个方法是:int totalSections = [self numberOfSectionsInTableView:tableView];
请问你post也可以用这个方法吗?UITableViewCell 子类在重用时泄漏。现在这不是一个选项,因为您正在使用 UITableViewCell。
注意事项 #1:如果项目在 ARC 中,请删除自动释放。
小记#2:使用
static NSString *CellIdentifier = @"Cell";
UITableViewCell *defaultCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
而不是:
static NSString *CellIdentifier = @"Cell";
UITableViewCell *defaultCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (defaultCell == nil) {
defaultCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
else{
NSLog(@"reusing the cell");
}
而且您不需要手动检查和分配新单元格。
感谢大家的帮助,以下解决方案对我有用
1.
-(void) viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kDefaultCellIdentifier];
[self.tableView registerNib:[UINib nibWithNibName:@"CustomTableViewCell" bundle:nil] forCellReuseIdentifier:kCustomTableCellIdentifier];
}
如@Péter Kovács 所述
2.
两个单元格都使用了 indexPath 方法
static NSString *CellIdentifier = kDefaultCellIdentifier;
UITableViewCell *defaultCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
static NSString *CellIdentifier = kCustomTableViewCellIdentifer;
UITableViewCell *defaultCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
3。
主要问题我在全局使用 defaultCell ,它也为 CustomTableViewCell 使 defaultCell 出队,因此在触发 CustomTableViewCell 块的情况下,它使两个单元格出队。根据行对相应的单元格进行出列解决了这个问题。