【问题标题】:UITableViewCells are deallocated after creationUITableViewCells 在创建后被释放
【发布时间】:2014-04-30 04:01:41
【问题描述】:
  • 我有一个UITableView,我用UITableViewCell 的几个不同子类填充它。
  • tableView:cellForRowAtIndexPath: 方法中创建单元后,立即将它们释放。
  • 我在每个自定义类中添加了一个NSLog 语句,以便在它们被释放时触发。
  • 这会导致各种问题,因为其中 1 个单元格是 UICollectionView 的代表,这是单元格的子视图。我正在初始化单元格,如下所示,以便我可以使用 xib 文件来创建它们。
  • 附加的是我的一个自定义单元格上的堆栈跟踪 pre-dealloc

笔尖注册

[_tableView registerNib:[UINib nibWithNibName:NSStringFromClass([HVStatusViewCell class]) bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"HVStatusViewCell"];
[_tableView registerNib:[UINib nibWithNibName:NSStringFromClass([HVActiveGroupCell class]) bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"HVActiveGroupCell"];

字典藏品部分信息

[tableData setObject:[NSNumber numberWithInt:1] forKey:@"s0-cellcount"];
[tableData setObject:@"HVStatusViewCell"        forKey:@"s0-cellidentifier"];
[tableData setObject:@"Status"                  forKey:@"s0-name"];

[tableData setObject:[NSNumber numberWithInt:1]   forKey:@"s1-cellcount"];
[tableData setObject:@"HVActiveGroupCell"         forKey:@"s1-cellidentifier"];
[tableData setObject:@"Active Emergency Contacts" forKey:@"s1-name"];

细胞创建

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *key             = [NSString stringWithFormat: @"s%li-cellidentifier", (long)indexPath.section];
    NSString *reuseIdentifier = [tableData valueForKey: key];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: reuseIdentifier];

    if (!cell) cell = [[NSClassFromString(reuseIdentifier) alloc] init];

    [cell setBackgroundColor: [UIColor clearColor]];
    return cell;
}

样本单元初始化

- (id) init
{
    self = [super init];

    if (self){
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil];
        self = [topLevelObjects firstObject];
    }

    return self;
}

堆栈跟踪:( 0 AngelAlert 0x0004de06 -[HVActiveGroupCell dealloc] + 70 1 UIKit 0x00bccb94 -[UIView release] + 89 2 CoreFoundation
0x026c1bf0 CFRelease + 272 3 核心基础
0x026e116e -[NSArrayM dealloc] + 142 4 libobjc.A.dylib
0x01ecb692 _ZN11objc_object17sidetable_releaseEb + 268 5
libobjc.A.dylib 0x01ecae81 objc_release + 49 6
libobjc.A.dylib 0x01ecbce7 _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 537 7 QuartzCore 0x02469268 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 108 8 CoreFoundation 0x0270836e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION
+ 30 9 CoreFoundation 0x027082bf __CFRunLoopDoObservers + 399 10 CoreFoundation 0x026e6254 __CFRunLoopRun + 1076 11 CoreFoundation 0x026e59d3 CFRunLoopRunSpecific + 467 12 CoreFoundation
0x026e57eb CFRunLoopRunInMode + 123 13 图形服务
0x03be65ee GSEventRunModal + 192 14 图形服务
0x03be642b GSEventRun + 104 15 UIKit
0x00b7af9b UIApplicationMain + 1225 16 AngelAlert
0x0005e21d 主 + 141 17 libdyld.dylib
0x033d0701 开始 + 1)

【问题讨论】:

  • 如果您注册了一个 nib,则无需检查单元格是否为 nil,因为它永远不会。此外,您不应该在单元格的类中覆盖 init,注册笔尖是您所要做的全部 - 表格视图负责为您加载笔尖。尝试删除它以查看是否可以解决问题。
  • 不走运。我继续删除了冗余代码,因为没有它它具有相同的功能。
  • 我在您的代码中看不到任何会导致单元格被释放的内容。是表视图本身,还是表视图控制器被释放?
  • 我只是仔细检查了一下,它不是。表视图保持分配状态,这令人困惑,因为我认为行在大多数情况下在拥有它们的表视图被释放时被释放。
  • 您是否确定单元格正在通过其 dealloc 方法中的日志释放?

标签: ios objective-c uitableview


【解决方案1】:

最后,我发现了这个问题,这是一个愚蠢的问题。我正在分配一个单元格来确定单元格高度:

- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *key = [NSString stringWithFormat: @"s%li-cellidentifier", (long)indexPath.section];
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier: [tableData valueForKey: key]];

    return cell.frame.size.height;
}
  • 被释放的单元格是在此方法中创建的单元格,而不是 UITableView 中的单元格
  • UICollectionView 的委托和数据源的连接指向 NSObject,而不是 UITableViewCell。我不确定这是否会导致任何问题,但我认为这值得一提。
  • TableView 中显示的单元格是持久的,这就解释了为什么在 dealloc 之前和之后记录它会给我相同的内存签名

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-20
    • 2011-09-13
    • 2011-09-23
    • 1970-01-01
    • 2016-04-25
    • 2022-07-08
    • 2013-05-24
    • 1970-01-01
    相关资源
    最近更新 更多