【问题标题】:App crashes on releasing custom Table Cell应用程序在发布自定义表格单元时崩溃
【发布时间】:2011-08-29 10:57:35
【问题描述】:

当我的自定义 TableViewCell 发布时,我的应用程序崩溃了。

Cell 在cellForRowAtIndexPath 中被初始化如下:

SearchTableViewCell *cell = (SearchTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[SearchTableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}

cell.nameLabel.text = @"some text";
cell.addressLabel.text = @"some more text";

cell 类本身是这样的

#import <UIKit/UIKit.h>

@class EGOImageView;

@interface SearchTableViewCell : UITableViewCell {
    UILabel *nameLabel;
    UILabel *addressLabel;
    EGOImageView *imageView;
}

@property (nonatomic, retain) UILabel *nameLabel;
@property (nonatomic, retain) UILabel *addressLabel;

- (UILabel *)labelWithColor:(UIColor*)color selectedColor:(UIColor*)selectedColor fontSize:(CGFloat)fontSize bold:(BOOL)bold frame:(CGRect)rect;
- (void)setThumb:(NSString*)thumb;

@end

.m

#import "SearchTableViewCell.h"
#import "EGOImageView.h"

#import "UIView+Additions.h"

@implementation SearchTableViewCell

@synthesize nameLabel = _nameLabel, addressLabel = _addressLabel;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {

        // Initialization code
        UIView *myContentView = self.contentView;

        // Name
        _nameLabel = [self labelWithColor:[UIColor blackColor] selectedColor:[UIColor whiteColor] fontSize:16.0f  bold:YES frame:CGRectMake(140.0f, 16.0f, 181.0f, 21.0f)];
        [myContentView addSubview:_nameLabel];
        [_nameLabel release];


        // Adress
        _addressLabel = [self labelWithColor:[UIColor blackColor] selectedColor:[UIColor whiteColor] fontSize:13.0f  bold:YES frame:CGRectMake(140.0f, _nameLabel.bottom, 181.0f, 21.0f)];
        [myContentView addSubview:_addressLabel];
        [_addressLabel release];


        // Image
        imageView = [[EGOImageView alloc] initWithPlaceholderImage:[UIImage imageNamed:@"placeholder.png"]];
        imageView.frame = CGRectMake(9.0f, 9.0f, 120.0f, 80.0f);
        [myContentView addSubview:imageView];
        [imageView release];

    }
    return self;
}

- (UILabel *)labelWithColor:(UIColor*)color selectedColor:(UIColor*)selectedColor fontSize:(CGFloat)fontSize bold:(BOOL)bold frame:(CGRect)rect {

    UIFont *font;
    if(bold) {
        font = [UIFont boldSystemFontOfSize:fontSize];
    } else {
        font = [UIFont systemFontOfSize:fontSize];
    }

    UILabel *label = [[UILabel alloc] initWithFrame:rect];
    label.backgroundColor = [UIColor clearColor];
    label.textColor = color;
    label.highlightedTextColor = selectedColor;
    label.font = font;

    return label;
}


- (void)setThumb:(NSString*)thumb {
    imageView.imageURL = [NSURL URLWithString:thumb];
}

- (void)willMoveToSuperview:(UIView *)newSuperview {
    [super willMoveToSuperview:newSuperview];

    if(!newSuperview) {
        [imageView cancelImageLoad];
    }
}

- (void)dealloc {
    [_addressLabel release];
    [_nameLabel release];
    [imageView release];
    [super dealloc];
}

@end

有人知道为什么我的应用在释放这样的单元格时会崩溃吗?注释掉dealloc方法上的2个标签和图像视图,应用程序不会崩溃,但是会有内存泄漏吗?

感谢所有提示!如果有不清楚的地方请留言!

【问题讨论】:

  • 它已经在那里称为@implementation SearchTableViewCell
  • 是的,对不起,我以为是别的,我刚刚删除了我的帖子。顺便说一句,我也会这样做。
  • 请检查您是否已在将这些对象添加到 myContentView 时释放这些对象。所以当 Dealloc 调用那些对象时没有内存所以我希望它崩溃。把 NsZombieEnalble Yes 在参数中然后检查哪个对象被释放
  • @Srinivas 查看我对 Seega 回答的评论
  • 由于您在 @synthesize 语句中创建了以下划线为前缀的 ivars,因此在 .h 中不使用前导下划线声明它们是不必要且具有误导性的。

标签: iphone ios ipad uitableview


【解决方案1】:

imageView 被释放两次,一次是在创建时:

imageView = [[EGOImageView alloc] initWithPlaceholderImage:[UIImage imageNamed:@"placeholder.png"]];
imageView.frame = CGRectMake(9.0f, 9.0f, 120.0f, 80.0f);
[myContentView addSubview:imageView];
[imageView release];

并且一旦在 dealloc 中:

- (void)dealloc {
    [_addressLabel release];
    [_nameLabel release];
    [imageView release];
    [super dealloc];
}

【讨论】:

  • addSubview增加retainCount?
  • 是的,但是当保留视图被释放时,它将释放它的所有内容视图。
  • 所以添加为子视图后不需要释放视图?
  • 一个基本规则是,谁增加保留计数,谁就减少它。所以视图增加了它负责减少它的保留计数。同样适用于集合类,如 NSArray 等。
  • 谢谢,那我把init方法里的release去掉,dealloc方法里全部释放。
【解决方案2】:
You already release the memory for that labels after adding to view,again you are trying to release  memory those objects are already relese  in dealloc method that's why it is killing.if you remove 3 statements in dealloc method  it will not crash.   

【讨论】:

  • 是的,我释放了它们。但它们是用“init”初始化的,并用“addSubview”添加到子视图中,所以它们的保留计数是两个。我认为释放它们一次应该不是问题?
【解决方案3】:

我认为问题在于您直接在 initWithStyle 函数中释放属性,并再次在 dealloc 中释放属性。尝试从 initWithStyle 中删除版本:

此外,您在接口中命名变量时不带 _,但在实现中使用 _ @synthesize'ing

【讨论】:

  • 是的,我释放了它们。但是它们是用“init”初始化的,然后用“addSubview”添加到子视图中,所以它们的保留计数是两个。我认为释放它们一次应该不是问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多