2

在使用 XCode 5 进行调试会话期间,我将如何显示 NSDecimal var 的实际值?我发现了这个问题,但这对我不起作用。输入摘要描述,就像{(int)[$VAR intValue]}只是导致消息“摘要不可用”。我应该补充一点,我的 NSDecimals 在一个数组(NSDecimal dataPoint[2];)中。

使用调试控制台通过上下文菜单或使用 p 打印 var 描述dataPoint[0]只会给我原始的 NSDecimal 视图:

Printing description of dataPoint[0]:
(NSDecimal) [0] = {
  _exponent = -1
  _length = 1
  _isNegative = 0
  _isCompact = 1
  _reserved = 0
  _mantissa = {
    [0] = 85
    [1] = 0
    [2] = 42703
    [3] = 65236
    [4] = 65534
    [5] = 65535
    [6] = 23752
    [7] = 29855
  }
}
4

2 回答 2

5

更新

Decimal在 Xcode 10.0 中,如果是 a 中的值Dictionary<String: Decimal>(并且可能在其他情况下),有一个 lldb 错误会使此答案打印错误的值。请参阅此问答Swift 错误报告 SR-8989。该错误已由 Xcode 11(可能更早)修复。

原来的

您可以通过安装NSDecimal将. 这称为类型摘要脚本,并记录在lldb 文档的此页面上的“PYTHON SCRIPTING”下。Foundation.DecimalNSDecimal

使用类型摘要脚本的一个优点是它不涉及在目标进程中运行代码,这对于某些目标可能很重要。

另一个优点是 Xcode 调试器的变量视图似乎更可靠地使用类型摘要脚本而不是使用hypercrypt 的答案中看到的摘要格式。我对摘要格式有疑问,但类型摘要脚本可以可靠地工作。

如果没有类型摘要脚本(或其他自定义),Xcode 会显示如下NSDecimal(或 Swift Decimal):

在键入摘要脚本之前

使用类型摘要脚本, Xcode 显示如下:

键入摘要脚本后

设置类型摘要脚本涉及两个步骤:

  1. 将脚本(如下所示)保存在某个文件中。我把它保存在~/.../lldb/Decimal.py.

  2. 添加命令以~/.lldbinit加载脚本。该命令应如下所示:

    command script import ~/.../lldb/Decimal.py
    

    将路径更改为您存储脚本的位置。

这是脚本。我也把它保存在这个要点中。

# Decimal / NSDecimal support for lldb
#
# Put this file somewhere, e.g. ~/.../lldb/Decimal.py
# Then add this line to ~/.lldbinit:
#     command script import ~/.../lldb/Decimal.py

import lldb

def stringForDecimal(sbValue, internal_dict):
    from decimal import Decimal, getcontext

    sbData = sbValue.GetData()
    if not sbData.IsValid():
        raise Exception('unable to get data: ' + sbError.GetCString())
    if sbData.GetByteSize() != 20:
        raise Exception('expected data to be 20 bytes but found ' + repr(sbData.GetByteSize()))

    sbError = lldb.SBError()
    exponent = sbData.GetSignedInt8(sbError, 0)
    if sbError.Fail():
        raise Exception('unable to read exponent byte: ' + sbError.GetCString())

    flags = sbData.GetUnsignedInt8(sbError, 1)
    if sbError.Fail():
        raise Exception('unable to read flags byte: ' + sbError.GetCString())
    length = flags & 0xf
    isNegative = (flags & 0x10) != 0

    if length == 0 and isNegative:
        return 'NaN'

    if length == 0:
        return '0'

    getcontext().prec = 200
    value = Decimal(0)
    scale = Decimal(1)
    for i in range(length):
        digit = sbData.GetUnsignedInt16(sbError, 4 + 2 * i)
        if sbError.Fail():
            raise Exception('unable to read memory: ' + sbError.GetCString())
        value += scale * Decimal(digit)
        scale *= 65536

    value = value.scaleb(exponent)
    if isNegative:
        value = -value

    return str(value)

def __lldb_init_module(debugger, internal_dict):
    print('registering Decimal type summaries')
    debugger.HandleCommand('type summary add Foundation.Decimal -F "' + __name__ + '.stringForDecimal"')
    debugger.HandleCommand('type summary add NSDecimal -F "' + __name__ + '.stringForDecimal"')
于 2018-10-10T22:41:11.483 回答
3

最简单的方法是在调试器中把它变成一个NSDecimalNumber,即

po [NSDecimalNumber decimalNumberWithDecimal:dataPoint[0]]

这将创建一个新NSDecimalNumber的打印一个很好的描述。你的NSDecimal问题是8.5。

(lldb) po [NSDecimalNumber decimalNumberWithDecimal:dataPoint[0]]
8.5

如果您想在变量视图中显示数字,它的摘要格式将是:

{[NSDecimalNumber decimalNumberWithDecimal:$VAR]}:s
于 2013-10-12T11:27:37.907 回答