【问题标题】:NSObject description and custom summaries in XcodeXcode 中的 NSObject 描述和自定义摘要
【发布时间】:2013-08-08 01:46:06
【问题描述】:

我覆盖了对象的 -(NSString*)description,但是 Xcode 总是在变量视图的摘要字段中显示 error: summary string parsing error

我目前的实现如下:

- (NSString*)description {
    return [NSString stringWithFormat:@"<%@ %p> x=%f, y=%f", self.class, self, _x, _y];
}

如果我在控制台中输入po objectName,LLDB 会按预期显示良好的输出,但是Xcode 和命令p objectName 总是指示错误,那么使汇总字段工作的正确调试描述格式是什么?值得注意的是,“p”命令的输出与您在 Xcode 中看到的 Foundation 类实例的摘要消息相同。

更新:

据我从“WWDC 2012 session Debugging in Xcode”中可以看出,自定义摘要只能使用自定义 python 脚本来实现。 -(NSString*)description-(NSString*)debugDescription 方法无论如何都没有连接到摘要消息。我以为是因为我显示了一个错误,但对于没有自己的格式化程序的类来说,这似乎是一条标准消息。

【问题讨论】:

  • 您说“覆盖”——这是子类还是类别?什么是超类?
  • 我不明白你说你在 Xcode 中做“p objectName”。在 Xcode 调试器中,我总是为一个对象使用pop 用于标量。
  • Hot Licks 需要注意的一点是,“p objectName”将适用于大多数标准 Foundation 对象(您的 NSStrings、您的 NSArrays 等),因为 lldb 有内置的格式化程序,它知道如何格式化对象而不在程序中运行任何代码。正如 Andy 在他的更新中指出的那样,您还可以在 Python 中为您自己的对象编写自己的自定义格式化程序——一旦掌握了它就很容易了。
  • @Andy - 变量显示很少起作用(并且经常锁定调试器),我几乎从不使用它。
  • 我同意 Enrico 的观点。如果您在 18 个月前对 Xcode 中的变量显示有问题,那么您几乎可以肯定是在使用 gdb(它实际上是在您的程序中运行代码以得出这些摘要)。这是有问题的,这就是为什么 lldb 完全采用了不同的技术。 Xcode 4.6 适用于标准类型——如果人们发现问题,请在bugreport.apple.com 提交错误报告

标签: objective-c xcode lldb


【解决方案1】:

我至少建议:

- (NSString*)description {
    return [NSString stringWithFormat:@"%@; x=%f, y=%f", [super description], _x, _y];
}

这样您就不会手动复制 NSObject 默认值,从而阻止您的超类可能选择包含的任何非默认行为。

除此之外,“摘要字符串解析错误”是一个 lldb 错误。它仅由调试器报告。根据its documentationpo 对 Objective-C 对象是正确的; p 用于 C 或 C++ 对象。所以你不需要注意那个错误——它本质上只是告诉你你使用了错误的 lldb 命令。

编辑:对于它的价值,CFArray 使用的方法是open source,看起来像:

static CFStringRef __CFArrayCopyDescription(CFTypeRef cf) {
    CFArrayRef array = (CFArrayRef)cf;
    CFMutableStringRef result;
    const CFArrayCallBacks *cb;
    CFAllocatorRef allocator;
    CFIndex idx, cnt;
    cnt = __CFArrayGetCount(array);
    allocator = CFGetAllocator(array);
    result = CFStringCreateMutable(allocator, 0);
    switch (__CFArrayGetType(array)) {
    case __kCFArrayImmutable:
    CFStringAppendFormat(result, NULL, CFSTR("<CFArray %p [%p]>{type = immutable, count = %u, values = (%s"), cf, allocator, cnt, cnt ? "\n" : "");
    break;
    case __kCFArrayDeque:
    CFStringAppendFormat(result, NULL, CFSTR("<CFArray %p [%p]>{type = mutable-small, count = %u, values = (%s"), cf, allocator, cnt, cnt ? "\n" : "");
    break;
    }
    cb = __CFArrayGetCallBacks(array);
    for (idx = 0; idx < cnt; idx++) {
    CFStringRef desc = NULL;
    const void *val = __CFArrayGetBucketAtIndex(array, idx)->_item;
    if (NULL != cb->copyDescription) {
        desc = (CFStringRef)INVOKE_CALLBACK1(cb->copyDescription, val);
    }
    if (NULL != desc) {
        CFStringAppendFormat(result, NULL, CFSTR("\t%u : %@\n"), idx, desc);
        CFRelease(desc);
    } else {
        CFStringAppendFormat(result, NULL, CFSTR("\t%u : <%p>\n"), idx, val);
    }
    }
    CFStringAppend(result, CFSTR(")}"));
    return result;
}

与上面的其他 cmets 一样,我愿意赌答案是:Xcode 的调试器在任何意义上都不聪明,而且绝对不够聪明,无法使用正确的 po 方法来获取 Objective- C 描述;如果您的对象是未变形的 Objective-C 对象,那么调试器将无法弄清楚。

【讨论】:

  • 感谢您的建议。我只是想有一种像 NSArray 那样的好提示,它显示数组中元素的数量。
  • ...您不想输入po?如果有区别,那么猜测是NSArray 是免费桥接的,因此它不仅是一个Objective-C 对象,而且至少是一种其他类型的东西。
  • Tommy,它是关于调试时在 Xcode 变量视图中显示的摘要消息,它非常有用,非常有用,因此您甚至不必输入任何内容。
猜你喜欢
  • 2016-01-20
  • 1970-01-01
  • 2017-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-30
  • 2014-11-24
  • 1970-01-01
相关资源
最近更新 更多