首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSMutableAttributedString致命异常: NSRangeException

NSMutableAttributedString致命异常: NSRangeException
EN

Stack Overflow用户
提问于 2016-02-03 10:20:12
回答 1查看 554关注 0票数 0

当我试图将属性应用到子字符串时,有时会出现以下代码崩溃:

代码语言:javascript
复制
// 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

下面是堆栈跟踪:

代码语言:javascript
复制
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**超出了originalString**,的范围,但我认为它永远不会发生。

谁能告诉我坠机的原因是什么?

EN

回答 1

Stack Overflow用户

发布于 2016-02-03 16:11:07

如果其他人遇到这样的问题,请张贴我的答案:

替换

代码语言:javascript
复制
let rangeOfSubString: NSRange = (originalString.lowercaseString as NSString).rangeOfString(searchSubString.lowercaseString)

使用

代码语言:javascript
复制
let rangeOfSubString: NSRange = (originalString as NSString).rangeOfString(searchSubString, options: .CaseInsensitiveSearch)

第一种计算子字符串范围的方法是错误的,原因是:

  • 它正在计算子字符串范围WRT小写版本,并将该范围的属性应用于原始字符串(非小写)。但是,在特殊字符情况下,使用上述方法计算的范围可能超出原始字符串范围,导致小写字符可能需要比大写版本更长,反之亦然。 即大写土耳其字母"İ“的长度为1,而小写版本”i̇“的长度为2。
  • 为了前夫。如果我们在“Hİ”(长度= 2)中搜索"İ“(长度= 2),第一个方法将给出一个范围(1,2),因为"İ”小写要求长度= 2,但是如果将范围(1,2)应用到"Hİ",它将超出其范围(0,2),或者如果原始字符串中有更多的字符,如"Hİabc",它将对应于"İa“,而这又是错误的。
  • 因此,计算范围WRT原始字符串以后,我需要应用到原始字符串本身的范围。

还请参阅苹果的文档:

lowercaseString: Case转换不一定是对称的,也不能产生与原始字符串长度相同的字符串。 lcString = myString lowercaseString; 可能不等于这一说法: lcString = [myString uppercaseString lowercaseString]; 例如,在德语中,大写形式为“SS”,因此将“Stra e”转换为大写,然后将小写转换为以下字符串序列: “Stra-e” “街” “街”

ref/occ/instp/NSString/lowercaseString

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35174261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档