当我尝试将属性应用于子字符串时,有时在以下代码中崩溃:
// Dummy strings
let originalString = "Some example string"
let searchSubString = "exam"
// Get range of sub-string for which new attributes are to be set.
let rangeOfSubString: NSRange = (originalString.lowercaseString as NSString).rangeOfString(searchSubString.lowercaseString)
// Apply new attributes to the sub-string in original string and show it in UILabel.
let attributedOriginalString = NSMutableAttributedString(string: originalString, attributes: [NSForegroundColorAttributeName : UIColor.blueColor()])
attributedOriginalString.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(14.0), range: rangeOfSubString)
attributedOriginalString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: rangeOfSubString)
self.textLabel.attributedText = attributedOriginalString
以下是堆栈跟踪:
Thread : Fatal Exception: NSRangeException
0 CoreFoundation 0x26cbefef __exceptionPreprocess
1 libobjc.A.dylib 0x35362c8b objc_exception_throw
2 CoreFoundation 0x26cbef35 -[NSException initWithCoder:]
3 Foundation 0x2793ac3b -[NSRLEArray objectAtIndex:effectiveRange:]
4 Foundation 0x27954b2d -[NSConcreteMutableAttributedString addAttribute:value:range:]
虽然我无法对其进行复制,但是我通过crashlytics获取了此崩溃日志。
崩溃日志似乎表明
rangeOfSubString
超出了originalString
的范围,但我认为它永远不会发生。 谁能指出崩溃的原因是什么?
最佳答案
如果其他人遇到此类问题,请发布我的答案:
更换
let rangeOfSubString: NSRange = (originalString.lowercaseString as NSString).rangeOfString(searchSubString.lowercaseString)
与
let rangeOfSubString: NSRange = (originalString as NSString).rangeOfString(searchSubString, options: .CaseInsensitiveSearch)
计算子字符串范围的第一种方法是错误原因:
但是,如果使用特殊字符,则使用上述方法计算的范围可能会超出原始字符串范围,因为小写字符可能比大写版本需要更多的长度,反之亦然。
即大写土耳其语字符“İ”的长度为1,而小写字母“i̇”的长度为2。
如果我们在“Hİ”(length = 2)中搜索“İ”,则第一种方法将为您提供一个range(1,2),因为小写的“İ”需要length = 2,但是如果您应用range(1,2 )到“Hİ”,它将超出范围(0,2)的范围,或者如果原始字符串中有更多字符(如“Hİabc”),则它将对应于“İa”,这又是错误的。
另请参阅苹果的文档:
lowercaseString:
Case transformations aren’t guaranteed to be symmetrical or to produce strings of the same lengths as the originals.
lcString = [myString lowercaseString];
might not be equal to this statement:
lcString = [[myString uppercaseString] lowercaseString];
For example, the uppercase form of “ß” in German is “SS”, so converting “Straße” to uppercase, then lowercase, produces this sequence of strings:
“Straße”
“STRASSE”
“strasse”
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/#//apple_ref/occ/instp/NSString/lowercaseString
关于ios - NSMutableAttributedString致命异常:NSRangeException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35174261/