Swift 为什么退格键的 strcmp 返回 -92?

标签 swift strcmp uitextfielddelegate backspace

我试图检测 UITextfieldDelegate 内部的退格键。 并找到了这个答案。 https://stackoverflow.com/a/49294870/911528

它工作正常。

但我不知道这个函数内部发生了什么。

let  char = string.cString(using: String.Encoding.utf8)!
let isBackSpace = strcmp(char, "\\b")

if isBackSpace == -92 {
    print("Backspace was pressed")
    return false
}
  1. 我不知道为什么退格的cString结果是0。 我可以在 XCode 上进行调试。请检查屏幕截图。

enter image description here

  1. 我不知道为什么退格键的 strcmp 大约为 0(据我在 XCode 调试器上得到的值)和“\b”字符返回 -92

enter image description here

我知道退格键的 ascii 码是 int 类型的“8”,所以我认为上面的函数应该像下面的代码。

// I thought this char would be "\b" of type char or 08 of type int
// but XCode give the value 0... I don't know why
let char = string.cString(using: String.Encoding.utf8)!

// as far as I know, strcmp returns positive value for equal values.
let isBackSpace = strcmp(char, "\\b")

// so I thought this would be
if isBackSpace > 0 {
    print("Backspace was pressed")
    return false // or true
}

谁能一步步解释这段代码? 谢谢。

引用:

https://linux.die.net/man/3/strcmp

https://theasciicode.com.ar/ascii-control-characters/backspace-ascii-code-8.html


现在我可以理解为什么人们使用该代码了, 上面的代码不正确。

尝试通过引用@Cristik 的回答来正确编辑。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        // backspace checking
        if string == "" {
            return true // or false
        }

最佳答案

让我们分析一下代码和流经该代码的数据:

  1. string 是一个空字符串,因为当您删除一个字符时,文本字段会尝试用“nothing”(一个空字符串)替换它
  2. 由于 #1,char 在内存中仅保存字符串终止符,即 \0:[0]
  3. "\\b"翻译成\b字符串,在内存中:[92, 98]
  4. 由于 #2 和 #3,strcmp 返回 0 - 92 => -92。

不确定为什么人们使用这个“算法”,他们可以简单地检查 string 参数是否为空。我假设他们首先尝试使用 \b 转义序列,这似乎不是一个有效的转义序列,所以他们添加了一个额外的 \ 字符,编译,但是导致转义序列不正确,因为 \\ 是反斜杠字符的转义序列,导致 b 部分被表示为纯字母。

委托(delegate)方法似乎没有报告退格,而是要求委托(delegate)方法对字符串进行操作。检测实际按键可能需要一些 UIEvent/RunLoop Hook 。

请注意,传递给 textField(_,shouldChangeCharactersIn:,replacementString:) 的空字符串并不总是意味着退格键被按下,剪切操作也可能导致空字符串被发送到代表。您可以尝试检查范围并假设按下退格键的范围为 1,但是用户也可以剪切一个字符...

关于Swift 为什么退格键的 strcmp 返回 -92?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51577566/

相关文章:

ios - 如何在具有无限行的 UILabel 上自动换行?

ios - 无法在 Testflight 的(Internal Tester)中开始测试

c - strcmp 在 c 中不工作

ios - 在不禁用 AutoLayout 的情况下更改按钮大小

比较 chars[] 不起作用

C - 比较数字字符串

swift - 使用核心数据中的索引来获取特定的二进制数据

ios - 如何在 Swift 中限制不同 UITextField 的文本长度?

Swift:UITableViewCell 中的 UITextField 委托(delegate)不起作用

ios - Swift模板库