ios - NSMutableAttributedString致命异常:NSRangeException

标签 ios crash nsrange nsmutableattributedstring nsrangeexception

当我尝试将属性应用于子字符串时,有时在以下代码中崩溃:

// 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)

计算子字符串范围的第一种方法是错误原因:
  • 正在计算子字符串范围WRT小写版本,并将该范围的属性应用到原始字符串(非小写)。
    但是,如果使用特殊字符,则使用上述方法计算的范围可能会超出原始字符串范围,因为小写字符可能比大写版本需要更多的长度,反之亦然。

    即大写土耳其语字符“İ”的长度为1,而小写字母“i̇”的长度为2。
  • 例如
    如果我们在“Hİ”(length = 2)中搜索“İ”,则第一种方法将为您提供一个range(1,2),因为小写的“İ”需要length = 2,但是如果您应用range(1,2 )到“Hİ”,它将超出范围(0,2)的范围,或者如果原始字符串中有更多字符(如“Hİabc”),则它将对应于“İa”,这又是错误的。
  • 因此,请稍后计算范围WRT原始字符串,我需要将该范围应用于原始字符串本身。

  • 另请参阅苹果的文档:

    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/

    相关文章:

    objective-c - 如何将单例类设置为委托(delegate)?

    ios - 来自字符串的 UUID 始终为零

    ios - contentOffset 在 UIScrollView 缩放结束时重置

    android - 使用 Phonegap 旋转 Android 设备时崩溃

    objective-c - NSMutableAttributedStrings - objectAtIndex:effectiveRange::Out of bounds

    ios - 快速多级导航看不到后退按钮

    crash - root(cern)因libpng问题Fedora 20而崩溃

    iphone - 从 Nib 加载 UITableView

    objective-c - 将带有 Switch 语句的 Swift convenience init 转换为 Objective-C

    ios - 如何将 NSRange 与此 NSString 一起使用?