带有 TextView 的属性文本导致崩溃

Posted

技术标签:

【中文标题】带有 TextView 的属性文本导致崩溃【英文标题】:Attributed text with TextView causing a crash 【发布时间】:2018-06-06 10:08:19 【问题描述】:

我有以下用于生成属性字符串的快速代码,

func getAttributedTermsAndServicesText() -> NSAttributedString 
    let text = StringConstants.RegisterConstants.termsOfUseLabelText
    let attributedString = NSMutableAttributedString(string: text)
    let termsRange = attributedString.mutableString.range(of: StringConstants.CommonConstants.termsOfUse)
    attributedString.addAttribute(NSAttributedStringKey.font, value: WebViewLinkType.termsOfUse.getLink(), range: termsRange)
    attributedString.addAttribute(NSAttributedStringKey.font, value: NSUnderlineStyle.styleSingle.rawValue, range: termsRange)

    let privacyRange = attributedString.mutableString.range(of: StringConstants.CommonConstants.privacyStatement)
    attributedString.addAttribute(NSAttributedStringKey.link, value: WebViewLinkType.privacyStatement.getLink(), range: privacyRange)
    attributedString.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue, range: privacyRange)

    print(attributedString.mutableString)
    return attributedString
  

此方法返回生成的属性字符串。但是在这行代码上崩溃了

//Generate attributed string
let attributedString = getAttributedTermsAndServicesText()

//crash after this line
cell.textView.attributedText = attributedString

它在控制台中打印以下详细信息,

-[__NSCFNumber _isDefaultFace]:无法识别的选择器发送到实例 0x15d0d9c0 ( "4 libc++abi.dylib 0x1ca0798f + 78", “5 libc++abi.dylib 0x1ca07493 __cxa_rethrow + 90”, “6 libobjc.A.dylib 0x1ca131ab objc_exception_rethrow + 42”, “7 CoreFoundation 0x1d699231 CFRunLoopRunSpecific + 600”, “8 CoreFoundation 0x1d698fd1 CFRunLoopRunInMode + 104”)2018-06-06 02:52:07.439226-0700 MyApp[370:63347] * 由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'-[__NSCFNumber _isDefaultFace]: 无法识别的选择器发送到实例 0x15d0d9c0' * 第一次抛出调用栈:(0x1d78bb3d 0x1ca13067 0x1d790fd1 0x1d78f0c3 0x1d6b7dc8 0x2292fe93 0x2292f727 0x2294bf4f 0x2294bc43 0x22a66523 0x1cc728 0x1c42c0 0x1cd0f0 0x22cebc13 0x22cebde5 0x22cd9d79 0x22cf08db 0x22a9cf0f 0x229bb483 0x20613cb7 0x20607d77 0x20607c05 0x20596839 0x205b4fdb 0x205248e3 0x1f9c31bf 0x1d9dca7f 0x1d734c19 0x1d74865f 0x1d747ebd 0x1d745eab 0x1d6991af 0x1d698fd1 0x1ee43b41 0x22a21a53 0x28d578 0x1ce864eb) libc++abi.dylib:终止于 NSException 类型的未捕获异常

但是,我仍然无法获得这次崩溃的确切原因。 以前有人遇到过这种问题吗?

【问题讨论】:

NSAttributedStringKey.font, value: NSUnderlineStyle.styleSingle.rawValue 这不是你想要的那种价值。您正在设置Int(封装在(NS)Number 中)而不是提供UIFont。我认为你放错了NSAttributedStringKey 这段代码最初在 swift 2 中,最近我使用 Xcode 自动转换将该代码转换为 swift 4.1 编译 将第二个的 .font 更改为 .understyle:attributedString.addAttribute(NSAttributedStringKey.font, value: NSUnderlineStyle.styleSingle.rawValue, range: termsRange) => attributedString.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue, range: termsRange) 否则没有意义。另外,请确保 .getLink() 正确返回 UIFont 感谢您的建议@Larme 【参考方案1】:

请添加字体名称和大小

func getAttributedTermsAndServicesText() -> NSAttributedString 
    let text = StringConstants.RegisterConstants.termsOfUseLabelText
    let attributedString = NSMutableAttributedString(string: text)
    let termsRange = attributedString.mutableString.range(of: StringConstants.CommonConstants.termsOfUse)

    attributedString.addAttribute(NSAttributedStringKey.link, value: WebViewLinkType.termsOfUse.getLink(), range: termsRange)
    attributedString.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue, range: termsRange)

    let privacyRange = attributedString.mutableString.range(of: StringConstants.CommonConstants.privacyStatement)
    attributedString.addAttribute(NSAttributedStringKey.link, value: WebViewLinkType.privacyStatement.getLink(), range: privacyRange)
    attributedString.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue, range: privacyRange)

    print(attributedString.mutableString)
    return attributedString
   

【讨论】:

为什么要同时使用NSFontAttributeNameNSAttributedStringKey.font?这很奇怪。 感谢您的努力和建议。根据这两个建议,我做出了回答。

以上是关于带有 TextView 的属性文本导致崩溃的主要内容,如果未能解决你的问题,请参考以下文章

带有两个 TextView 和省略号的布局

[执行textView命令时应用程序崩溃

设置文本时 TextView 崩溃

Android 控件一 TextView

可以在 TextView 文本中为单词加下划线

使用 Kotlin Coroutines 更新我的 TextView 会导致它崩溃: