Tencent / QMUI_iOS

QMUI iOS——致力于提高项目 UI 开发效率的解决方案
http://qmuiteam.com/ios
Other
7.08k stars 1.38k forks source link

QMUITableViewCell 初始化方法在swift中导致内存问题 #1320

Closed ziruozimi closed 2 years ago

ziruozimi commented 2 years ago

Bug 表现 QMUITableViewCell 初始化方法

- (instancetype)initForTableView:(UITableView *)tableView withStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self.initByTableView = YES;
    if (self = [self initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        self.parentTableView = tableView;
        [self didInitializeWithStyle:style];// 因为设置了 parentTableView,样式可能都需要变,所以这里重新执行一次 didInitializeWithStyle: 里的 qmui_styledAsQMUITableViewCell
    }
    return self;
}

在swift中

final class DemoTableViewCell: QMUITableViewCell {
    let label = DemoLabel()
}

label会被初始化两次,当退出页面时还有一个label存在于内存中

截图 image image image

如何重现 Demo.zip

预期的表现 如果调用super则表现正常

- (instancetype)initForTableView:(UITableView *)tableView withStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self.initByTableView = YES;
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        self.parentTableView = tableView;
        [self didInitializeWithStyle:style];// 因为设置了 parentTableView,样式可能都需要变,所以这里重新执行一次 didInitializeWithStyle: 里的 qmui_styledAsQMUITableViewCell
    }
    return self;
}

其他信息

MoLice commented 2 years ago

已发布 4.4.0 修复该问题。

MoLice commented 2 years ago

发现 4.4.0 的修改方式会导致以下问题:

业务某个 cell 继承自 QMUITableViewCell。当业务要重写 init 方法时,他沿用系统默认的思路,去重写 initWithStyle:reuseIdentifier: 方法,然后在业务 vc 里使用这个 cell 时又是用 QMUI 提供的 initForTableView:withStyle: 系列方法去初始化。

如果这种场景,在升级到 4.4.0 后就会发现 initForTableView 调用时无法触发 cell 内部重写的 initWithStyle:。

MoLice commented 2 years ago

已发布 4.4.1,回退该修改,这种情况目前暂无合适的建议,可以考虑业务换个写法。