【问题标题】:Why is Xcode's Variables View's "Edit Value" not changing the variable value?为什么 Xcode 的变量视图的“编辑值”没有改变变量值?
【发布时间】:2015-09-30 18:02:13
【问题描述】:

在 Xcode 的变量视图中,在调试区域的右侧,当应用程序正在运行并在断点处暂停时,您可以右键单击变量并选择“编辑值”。

对于快速字符串,它是灰色的,我可以想象为什么会出现这种情况。但是即使对于一个简单的 int,它也会弹出一个编辑框来输入一个新的值,但是在点击该值之后会停留在旧值。即使对于在代码期间更改的 var 也是如此。

更新:如下面 Jim 的回答所示,您应该可以使用 lldb 表达式命令设置值,但是,尽管 Xcode 会告诉您它已更改,但实际上并没有更改该值。

这是坏了,还是你需要做一些特定的事情才能让它工作?谢谢。

更新:这是一个编译错误 - 请参阅 Jim's comment。这是一个解决方法...

    println("Before lldb change, foo is \(foo)")
    //make compiler think foo may change, so I can change it myself at the console
    if count("abcd") == 0 { foo = 0 }
    println("After lldb change, code now thinks foo is \(foo)")

【问题讨论】:

    标签: ios iphone xcode debugging variables


    【解决方案1】:

    大多数 Swift 实体,当然是字符串,但即使是像 Int 这样的“简单”类型,实际上都不是简单类型。您在变量视图中看到的值是由 lldb 中的数据格式化程序构造的,这些格式化程序设置为在不运行任何代码的情况下呈现有用的值视图(出于性能原因。)他们知道如何 grub 并获取 Swift 类型的内容,但我们没有教他们如何编辑值,只是呈现出来。

    如果你想改变一个值,你需要在你的程序中运行一些代码来做到这一点,你可以使用 lldb 控制台中的expression 命令来做到这一点。因此,例如,如果您有一个名为 foo 的 Int 变量,您可以这样做:

    (lldb) expr foo = 12

    这将编译并执行该代码片段,当然 Swift 编译器确实知道如何更改这些 Swift 值,因此生成的代码将正确设置值。

    请注意,似乎 swift 编译器有时会将值复制到寄存器并从寄存器中使用它,而不会在调试信息中表明这一事实。如果发生这种情况,lldb 将报告它在调试信息指向的位置设置的值,但代码实际上会使用临时值。我已经向 swift 编译器提交了一个错误,演示了一个实例。

    【讨论】:

    • 这会导致更奇怪的行为!尽管变量视图上的值和“(lldb) po foo”现在会显示 12,但实际程序中的值不会改变。代码中后续的 println 命令仍然会打印旧值,if 语句会根据旧值执行。
    • 注意:即使我使用 'var foo = count(testString)' 之类的东西设置原始值也是如此,因此编译器不“知道”该值是什么。跨度>
    • 不要做'var foo = count(testString)'。这将创建一个新的局部变量,该变量在表达式评估期间持续存在。关闭“var”,它应该可以工作。
    • 抱歉不清楚 - 'var foo = count(testString)' 在代码中,而不是控制台中。我在控制台中输入'(lldb) expr foo = 12',控制台说值已经改变,变量视图说值已经改变,应用程序忽略它并继续使用旧值。
    • 有趣。这是编译器中的一个错误。因为它知道 foo 在你设置它和使用它的时间之间没有改变,所以它将值存储在某个临时位置 - 很可能是一个寄存器 - 并从寄存器中访问它。这是一件好事,但它忽略了告诉调试器实时版本现在在寄存器中。您可以这样说,因为如果您创建一个接受 inout Int 的 func,并在设置变量和读取它之间将 foo 传递给该调用,那么代码路径将受到您的“设置”的影响。
    【解决方案2】:

    如果是常量Integers,你不能直接设置任何东西。

    但是,假设您将变量作为参数传递给您的函数:

    value = (AnyObject!) Int64(38) instance_type = (Builtin.RawPointer) 0xb000000000000263

    请注意,这个以 1 开头的地址并不是真正的指针。现在假设您想用 64 替换值 38。您输入:

    po Unmanaged.passUnretained(64).toOpaque() 你得到了常量 64 的神奇伪地址:

    0xb000000000000403 - _rawValue : (Opaque Value)

    然后您将 0xb000000000000263 替换为 0xb000000000000403 并且您的常量已更改。

    上帝,我爱斯威夫特

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-06
      • 2014-12-02
      • 1970-01-01
      • 1970-01-01
      • 2016-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多