Что происходит при печати объекта Swift (po) в lldb?

на Objective-C, когда NSLog объект или po его в lldb объект принял description сообщение.

в Swift, однако, поведение кажется другим. Я реализовал оба Printable (требуется description свойства) и DebugPrintable (что, в свою очередь, требует свойства с именем debugDescription). Если я попытаюсь println() объект или po it, ни одно из этих свойств не вызывается.

что происходит? Для чего тогда эти протоколы??

3 ответов


есть известная проблема, что Printable игнорируется Swift REPL (т. е. что-либо на игровой площадке или управляется xcrun swift в командной строке), но распознаваемые компилятором (скомпилированные приложения в симуляторе или xcrun swiftc).

например, вот код " foo.swift":

struct Person : Printable {
    let name: String

    var description: String {
        return "\(name)"
    }
}

let me = Person(name: "Nate")
println(me)

если я запускаю его с помощью REPL, я получаю это:

$ xcrun swift foo.swift 
foo.Person

но если я скомпилировать его, а затем запустить его, он использует description компьютерная свойство:

$ xcrun -sdk macosx swiftc foo.swift ; ./foo
Nate

на DebugPrintable протокол полезен, если вы хотите иметь возможность использовать debugPrint и debugPrintln функции -- в скомпилированном коде они распечатывают экземпляр debugDescription собственность.


чтобы добавить еще несколько деталей к ответу Нейта:

  • в Xcode 6, Когда вы пытаетесь " по " быстрому объекту, происходит одна из двух вещей:

    • объект фактически является объектом Objective-C (например, NSWindow, NSString) или необязательным такого типа. В этом случае LLDB разворачивает при необходимости, а затем вызывает NSPrintForDebugger(objcpointer). Это означает, что объекты ObjC должны "po" то же самое в Swift, что и в Цель-С

    • объект на самом деле является объектом Swift. В этом случае LLDB использует свои собственные форматеры данных для печати объекта с несколькими незначительными настройками, чтобы придать"po" -esque вид, но независимо от того, какие протоколы реализует ваш объект, они игнорируются

в качестве будущего улучшения идея заключается в том, что LLDB сможет запросить стандартную библиотеку Swift toDebugString (object) и позволить библиотеке Swift обрабатывать детали того, что операции означают-подобно NSPrintForDebugger () в мире Objective-C.

в этом расширенном Юниверсе контракт стандартной библиотеки вполне может заключаться в том, что реализация Printable или DebugPrintable повлияет на результат toDebugString(). LLDB автоматически поймет, потому что это просто делегирование ответственности.

даже в такой расширенной вселенной ваш пробег в режиме REPL будет отличаться из-за ограничений JIT. Кстати, то же самое ограничение делает невозможным определение типа на игровой площадке и настройку способа его представления (что потребует реализации хотя бы одного из протоколов Reflectable/Mirror)


попробуй:

dump(object)

Se подробнее об этом здесь