iOS UITableViewCell中的Masonry速度非常慢



我正在为iPhone开发一个iOS应用程序,并且有一个UITableView,其中包含具有可变高度的自定义单元格。对于单元格的布局,我使用砌体:https://github.com/Masonry/Masonry.一切都在按我的喜好渲染,我唯一的问题是,当一个新的单元格出现在屏幕上时,会有一些滞后,足以严重阻碍用户体验。我对执行时间做了一些测试,似乎大部分滞后都在函数内部:

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

在iPhone 5上,执行时间大约是十分之一秒。此外,我发现大部分时间都发生在函数中:

-(void)updateConstraints;

的自定义UITableViewCell类。在这个函数中,我使用Masonry设置了单元中视图的各种约束。因此,我基本上将这种滞后缩小到了Masonry呼叫。如果你想知道,整个功能看起来是这样的:

-(void)updateConstraints
{
    [super updateConstraints];
    [self.thumbnailImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.contentView.mas_top).offset(5);
        make.left.equalTo(self.contentView.mas_left).offset(5);
        make.right.equalTo(self.contentView.mas_right).offset(-5);
        make.height.equalTo(@(self.thumbnailImageView.frame.size.width)).with.priorityHigh();
    }];
    [self.likeButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.thumbnailImageView.mas_bottom).offset(5);
        make.left.equalTo(self.captionTextView.mas_right);
    }];
    [self.dislikeButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.thumbnailImageView.mas_bottom).offset(5);
        make.left.equalTo(self.likeButton.mas_right);
        make.right.equalTo(self.contentView.mas_right).offset(5);
    }];
    [self.captionTextView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.thumbnailImageView.mas_bottom).offset(5);
        make.left.equalTo(self.contentView.mas_left);
        make.right.equalTo(self.likeButton.mas_left);
        make.height.equalTo(@([self captionHeight]));
    }];
    [self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.greaterThanOrEqualTo(self.captionTextView.mas_bottom).offset(5).with.priorityHigh();
        make.bottom.equalTo(self.contentView.mas_bottom);
        make.left.equalTo(self.contentView.mas_left).offset(5);
    }];
    [self.scoreLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.captionTextView.mas_right);
        make.top.equalTo(self.likeButton.mas_bottom);
        make.right.equalTo(self.contentView.mas_right);
    }];
    [self.numCommentsLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.greaterThanOrEqualTo(self.scoreLabel.mas_top);
        make.bottom.equalTo(self.contentView.mas_bottom);
        make.right.equalTo(self.contentView.mas_right);
    }];
}

我想知道的是,是否有任何方法可以减少执行时间并消除这种明显的滞后。我为每个单元格设置的约束对每个单元格都是完全相同的约束,只有少数例外。这只是AutoLayout的问题,还是我正在做的事情有很大问题?总的来说,这只是一个糟糕的方法吗?

经过更多的探索,我发现问题的根本原因是我的细胞没有得到适当的回收。我的cellForRowAtIndexPath函数最初看起来是这样的:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    static NSString *postTableIdentifier = @"PostTableCell";
    PostTableViewCell *cell = (PostTableViewCell *)[tableView dequeueReusableCellWithIdentifier:postTableIdentifier];
    if (cell == nil)
    {       
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:postTableIdentifier owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }
    //rest of function...
}

在这里,tableView查找reuseIdentifier为@"PostTableCell"的单元格。但是,loadNibNamed:函数没有设置单元格的reuseIdentifier,因此dequeReusableCellWithIdentifier:无法找到回收的单元格。我在这里找到了一个很好的解决方案:如何回收从XIB创建的UITableViewCell对象?我会让它自己回答,但是我的新代码是这样的:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    static NSString *postTableIdentifier = @"PostTableCell";
    PostTableViewCell *cell = (PostTableViewCell *)[tableView dequeueReusableCellWithIdentifier:postTableIdentifier];
    if (cell == nil)
    {
        //register nib once
        [tableView registerNib:[UINib nibWithNibName:postTableIdentifier bundle:nil] forCellReuseIdentifier:postTableIdentifier];
        cell = (PostTableViewCell *)[tableView dequeueReusableCellWithIdentifier:postTableIdentifier];
    }
    //rest of function...
}

最新更新