最近項目遇到的問題,因爲後臺返回的數據是HTML字符串,所以就按照常規處理方式把HTML字符串轉換成富文本的字符串來處理,事實證明,tableview會非常卡,並且造成線程阻塞,無法響應事件
1
2
3
4
5
6
|
在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
2
3
4
5
6
7
8
9
10
11
12
13
14
|
//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一定要慎用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
-( 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字符串的標籤字符會越來越少,而每次掃描的初始位置相對沒有變化都停留在上一次掃描結束的位置,即"<"標籤的前面。