UITableView 中的二进制数据导致高 CPU 加载和冻结

Binary data in UITableView cause high CPU Load and freezing

我有一些 HTML 数据,我将其作为 Binary Data 存储在 CoreData 中。我在 UITableViewCells 中将其显示为 NSMutableAttributedString,如下所示:

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

    NSManagedObject *row = [self.messagesFRC objectAtIndexPath:indexPath];

    MessageLTableViewCell *cell = (MessageLTableViewCell *)[self.tableView dequeueReusableCellWithIdentifier:@"MSGCELLID" forIndexPath:indexPath];

    NSString *messageText = [[NSString alloc] initWithData:[row valueForKey:@"message_text"] encoding:NSUTF8StringEncoding];

    messageText = [NSString stringWithFormat:@"<style>body{font-family: '%@';direction:rtl;float:right; font-size:%fpx;}</style>%@", FONT_TEXT, 17.0, messageText];

    NSError *err = nil;
    NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc]
      initWithData:[messageText dataUsingEncoding:NSUTF8StringEncoding]
      options:
      @{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,
        NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding),
    }
    documentAttributes: nil
    error: &err];


    if(err)
        NSLog(@"Unable to parse label text: %@", err);
    cell.messageText.attributedText = attrStr;


    return cell;

}

问题是它会导致高 CPU 负载,并且 UITableView 在滚动时冻结。以最佳性能处理它的最佳实践解决方案是什么?

首先,您的托管对象子类中应该有此逻辑。这种数据操作的繁重工作不属于 table 视图数据源。为此,为您的托管对象子类提供一个方便的方法attributedString

其次,您可以将 HTML 存储为文本,即 String 类型。这将具有额外的优势,即它将变得可搜索。

至于性能,好像用NSHTMLTextDocumentType的数据方法真的很慢(评论里有人提到了一个测试here)。另一种方法是使用 NSRanges,如果 HTML 字符串不太复杂,这是可行的。