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