<p>??比較長的一段時間以來稿湿,一直有一個IOS7下的crash不時的出現(xiàn)集峦,近期終于找到一個crash現(xiàn)場延蟹,實(shí)在是個令人興奮的消息评矩。</p>
<p>二話不說,先上堆棧:</p>
<p>從堆棧上可以看出阱飘,crash發(fā)生在系統(tǒng)的API里面斥杜。而且僅僅是IOS8以下的系統(tǒng)才會發(fā)生,說明在IOS8以上的系統(tǒng)沥匈,蘋果已經(jīng)意識到了這個問題蔗喂,將其修復(fù)了。
</p>
<p>
那么導(dǎo)致問題的原因究竟是什么高帖?
</p>
<p>@"-信 仰缰儿。????????:";
</p>
<p>如上所示试躏,就是這個莫名其妙的字符串能岩,導(dǎo)致的屬性文本在計算高度的時候直接crash融蹂。利用萬能的谷歌一查腺阳,這句是個阿拉伯語掀泳,大意是“真主偉大”盖溺。為何阿拉伯語會導(dǎo)致IOS的系統(tǒng)API產(chǎn)生crash遇革?
</p>
<p>引用知乎上大牛們的解釋:“這個 bug 應(yīng)該歸結(jié)為蘋果從 WebCore 到 CoreText 都存在設(shè)計缺陷沉噩,對從右往左的編輯方向支持的不好吏祸,設(shè)計上沒有考慮這種字符序列对蒲,而不能單純說 WebCore 或者 CoreText 的某個地方有個小 bug。"
</p>
<p>上面這個問題算是見過的最為接近的問題了贡翘,而且crash的堆棧也及其類似蹈矮。所不同的是,上面的問題發(fā)生IOS6上面(這種老古董的系統(tǒng)大家就別用了吧4补馈)含滴,據(jù)說在IOS7上面已經(jīng)得到修復(fù)。不過現(xiàn)實(shí)是目前在處理屬性文本中含有阿拉伯文時丐巫,IOS系統(tǒng)的表現(xiàn)就是不穩(wěn)定谈况。
既然是這樣勺美,那一種處理方法就是將文本中的阿拉伯文過濾掉了,替換成空格或者其它什么的碑韵。以便使用不包含阿拉伯文的文本來計算size赡茸。
需要如何替換?
這里就要用到unicode編碼的相關(guān)知識了祝闻。阿拉伯文一般使用unicode編碼占卧,我們找到它們的具體位置(unicode字符編碼表):
阿拉伯文的范圍為0x600到0x6FF。這樣通過IOS的NSMutableCharacterSet對象联喘,我們就可以找到需要過濾的字符集合华蜒。
簡單的算法如下:
<code>
+ (NSCharacterSet *)tExceptSet
{
// 異常字符集合
static NSCharacterSet *exceptSet;
if (exceptSet == nil)
{
NSMutableCharacterSet *aCharacterSet = [[NSMutableCharacterSet alloc] init];
NSRange lcEnglishRange;
lcEnglishRange.location = (unsigned int)0x0600;
lcEnglishRange.length = (unsigned int)0x06ff - (unsigned int)0x0600;
[aCharacterSet addCharactersInRange:lcEnglishRange];
exceptSet = aCharacterSet;
}
return exceptSet;
}
- (NSString )ttLegalNickName:(NSString)nickName
{
NSString* legalNickName = nickName;
if(!IS_IOS_UPPER(@"8.0")) {
NSCharacterSet *illegalCharacterSet = [CommentInfo tExceptSet];
legalNickName = [[nickName componentsSeparatedByCharactersInSet:illegalCharacterSet] componentsJoinedByString:@""];
}
return legalNickName;
}
</code>
</p>
<p>
??在應(yīng)用上述過濾方法之后,部分IOS8以下的系統(tǒng)會受到小小的影響豁遭,但是相比較直接閃退而言叭喜,這樣還算是比較令人接受的了。當(dāng)然過濾只是一種方式蓖谢,另外換一個場景捂蕴,直接用上面的阿拉伯字符串算屬性文本的高度,當(dāng)文本很簡單的時候并未發(fā)生Crash闪幽∩侗妫或許這個問題還有更好的解決方案,各位如果知道盯腌,不妨告訴我溉知。。
</p>