2015-04-01 56 views
0

我正在为iPhone的iOS应用程序工作,并且具有带可变高度的自定义单元格的UITableView。我正在使用的单元布局砌体https://github.com/Masonry/Masonry。一切都在按照我的喜好渲染,唯一的问题是,当一个新的单元进入屏幕时会有一些滞后,足以严重阻碍用户体验。我做了执行时间的一些测试,似乎这种滞后的大部分是函数中:iOS中的砌体UITableViewCell非常慢

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

的执行时间是第二对iPhone 5的十分之一的量级上。另外,我有发现大部分时间发生在这个函数中:

-(void)updateConstraints; 

我的自定义UITableViewCell类。在这个功能中,我使用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的一个问题,或者是对我所做的事情非常错误?总的来说,这只是一个坏方法?

+0

更新约束可以被调用多次。你应该确保你没有多次添加所有的约束条件。你也应该在最后调用'[super updateConstraints]'而不是在开始。 – dan 2015-04-01 22:28:06

回答

0

经过更多的探索后,我发现问题的根本原因是我的细胞未被正确回收。我的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查找与@“PostTableCell”的reuseIdentifier细胞。但是,loadNibNamed:函数不会设置单元的reuseIdentifier,因此dequeReusableCellWithIdentifier:找不到循环单元。我发现了一个很好的解决这个问题就在这里:How can I recycle UITableViewCell objects created from a XIB?我会让它回答本身, 但我的新代码如下所示:

- (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... 
}