Что происходит при печати объекта 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)