【问题标题】:Crash when adding string from regex capture to attributed string将字符串从正则表达式捕获添加到属性字符串时崩溃
【发布时间】:2019-07-31 13:38:18
【问题描述】:

我正在尝试使用以下方法在属性字符串中创建链接:

    matches = regex.matches(in: strings, options: [], range: NSRange(strings.startIndex..., in: strings))

        for match in matches {

            rangeBetweenQuotes = match.range(at: 1)

            let swiftRange = Range(rangeBetweenQuotes, in: strings)!

            let link:String = String(strings[swiftRange])

              attributedString.addAttribute(.link, value: link, range: rangeBetweenQuotes)

        }

如果我只是添加一个字体属性而不是一个链接,我知道上述方法是有效的。所以我的正则表达式有效。但是,在添加链接属性时,我遇到了问题。当我编译上面编写的代码并运行应用程序时,我点击链接并得到一个错误:线程 1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0。它出现在应用程序委托类中。

据我所知,最后两行代码抛出了错误。

     let link:String = String(strings[swiftRange])

          attributedString.addAttribute(.link, value: link, range:  rangeBetweenQuotes)

为了调试,我在上面的最后两行代码之间放置了一个断点。我可以看到变量 link 包含正确的字符串。该字符串也在addAttributevalue 参数中找到。

在运行时点击链接时会引发错误。我知道是这种情况,因为我可以用字符串文字(即"test")替换或分配link,并且链接工作正常,我可以使用

func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {

将“测试”字符串文字分配给插座。

使用调试器,我在valuevalue 参数中的link 变量内的向下钻取菜单中发现了以下内容addAttribute.

(BridgeObject) _object = 从值中提取数据失败

这表明变量有问题。不?

我尝试使用URL(string:"")String 类型的link 变量转换为URL,这也不起作用。

【问题讨论】:

    标签: ios swift cocoa-touch nsattributedstring


    【解决方案1】:

    我相信答案涉及以下函数中的 URL 类型是否与传递给它的任何类型兼容。

     func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool  
    

    下面的代码可以正常工作而不会引发错误。看看 URL(fileURLWithPath: )

         ... let swiftRange = Range(rangeBetweenQuotes, in: strings)!
    
            let link:String = String(strings[swiftRange])
    
              let link2 = URL(fileURLWithPath: link)
    
                 attributedString.addAttribute(.link, value: link2, range: rangeBetweenQuotes)
    

    我不断遇到的崩溃并不是因为执行函数 addAttribute 参数 value 时出现错误,该函数采用 Any 对象类型。在调试错误时,发现addAttribute中的参数value中包含了我传入的字符串值。如上所述,问题源于函数:

    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool 
    

    接受一个 URL。当我尝试使用

    将字符串类型 link 转换为 URL 时
    URL(string:"")
    

    转换失败。我不断得到一个空值,这在点击链接时当然会引发错误。但是,当字符串类型变量时,我可以安全地将变量传递给参数 shouldInteractWith URL:URL 转换为 URL 使用:

     URL(fileURLWithPath: link)
    

    我仍然不明白为什么 shouldInteractWith URL:URL 接受字符串文字,而 String(string[swiftRange]), supra 不起作用。有什么想法吗?

    编辑...进一步解释

    我知道为什么 URL 类型接受一个字符串文字而不接受另一个字符串文字的答案。有效的 URL 类型在字符串中不能有空格。 URL(fileURLWithPath:) 有效,因为它用 %20 填充空白。

    我希望这对以后的人有所帮助。

    【讨论】:

      【解决方案2】:

      一个原因可能是 NSRangeRange<String.Index> 的转换,反之亦然。强烈建议您不要使用string.countNSString 绕道。

      有方便的 API 可以安全地转换类型

      matches = regex.matches(in: string, range: NSRange(string.startIndex..., in: string))
      

      let swiftRange = Range(rangeBetweenQuotes, in: string)!
      let link = String(string[swiftRange])
      

      【讨论】:

      • 不幸的是,我没有运气就实施了您的建议。尽管如此,我将继续使用建议的 API。感谢您参与此事。 -基思
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-20
      • 2017-08-01
      • 2017-03-19
      • 1970-01-01
      • 2016-12-15
      • 1970-01-01
      相关资源
      最近更新 更多