最近项目遇到的问题,因为后台返回的数据是HTML字符串,所以就按照常规处理方式把HTML字符串转换成富文本的字符串来处理,事实证明,tableview会非常卡,并且造成线程阻塞,无法响应事件
- 在cell的model的set方法中刚开始是这样操作的~~~~~非常卡
- -(void)setModel:(XAPublicWelfareModel *)model{
- //这就是耗时操作的代码
- NSAttributedString * attrStr = [[NSAttributedString alloc]initWithData:[model.content dataUsingEncoding:NSUnicodeStringEncoding] options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType} documentAttributes:nil error:nil];
- self.introLabel.attributedText = attrStr;
- }
解决方案1
首先我想到的是把耗时操作放在子线程来操作
- //1.获取一个全局串行队列
- dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
- //2.把任务添加到队列中执行
- dispatch_async(queue, ^{
- NSAttributedString * attrStr = [[NSAttributedString alloc]initWithData:[model.content dataUsingEncoding:NSUnicodeStringEncoding] options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType} documentAttributes:nil error:nil];
- dispatch_async(dispatch_get_main_queue(), ^{
- self.introLabel.attributedText = attrStr;
- });
- });
虽然解决了,卡屏,线程阻塞的问题,但是并没有解决根本问题,数据处理还是很慢,不建议使用
解决方案2
因为是cell展示,所以只需要展示文本信息就行,那就过滤掉HTML标签,瞬间解决所有问题。所以在列表展示数据的时候HTML转换NSAttributedString一定要慎用
- -(void)setModel:(XAPublicWelfareModel *)model{
- //调用去除HTML标签的方法,直接赋值。
- self.introLabel.text = [self filterHTML:model.content];
- }
- //去除标签的方法
- -(NSString *)filterHTML:(NSString *)html
- {
- NSScanner * scanner = [NSScanner scannerWithString:html];
- NSString * text = nil;
- while([scanner isAtEnd]==NO)
- {
- [scanner scanUpToString:@"<" intoString:nil];
- [scanner scanUpToString:@">" intoString:&text];
- html = [html stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%@>",text] withString:@""];
- //去除空格
- html = [html stringByReplacingOccurrencesOfString:@" " withString:@""];
- }
- return html;
- }
下面简单介绍一下NSScanner
NSScanner是一个类,用于在字符串中扫描指定的字符,翻译成我们需要的字符串或者数字,核心就是位置的移动 即scanLocation的移动变化
在上面的方法中首先指明了要扫描的对象 html(NSString) NSString * text 很重要 把我们要扫描出来的字符串存到text里面
而这个扫描到的字符串就是>之前的字符串 scanUpToString这个方法的意思是将scanLocation停留在>之前 并把之前的字符串传给text。
回头来看看我们去除html标签的方法 整个过程都是在扫描过程中进行的NSScanner在执行scanUpToString这个方法时一旦扫描到需要的字符串比如例子中的“<”,其scanLocation就会变为html的初始位置。所以,要在执行完一次完整的扫描后 把html标签用空字符串替换掉,在进行下一次扫描,也就是说再while中 html字符串的标签字符会越来越少,而每次扫描的初始位置相对没有变化都停留在上一次扫描结束的位置,即"<"标签的前面。