Подтвердить что ты не робот

Взаимодействие с быстрым объектом с памятью в отладчике

Предположим, я знаю, основываясь на более раннем выпуске консоли, что в некоторой ячейке памяти объект представляет интерес:

<MySpecialObject:0x7a5125a0 This is a description of my special object>

В отладчике ObjC я мог бы сделать что-то вроде po [0x7a5125a0 myMethod:arg1 arg2:arg2] для взаимодействия с этим объектом в отладчике.

Я мог бы также сделать это:

(lldb) expr MySpecialObject *$foo = 0x7a5125a0
(lldb) po [foo myMethod:arg1 arg2:arg2]

Каков способ выполнить этот эффект (взаимодействовать с объектом в lldb с учетом его адреса памяти) при отладке программы Swift?

4b9b3361

Ответ 1

Одна вещь, которую вы могли бы попробовать, это следующее:

(lldb) expr -l objc++ -O -- [(id)0xmyFancyAddressGoesHere selector]

Ваш пробег может варьироваться, но по существу это прославленная версия того, что вы делали бы в ObjC (за исключением того, что теперь вы находитесь в Swift-land, поэтому вам нужно заставить оценщика выражения в режиме ObjC (-l objС++) и вы не можете полагаться на псевдоним "po", поэтому вам нужно явно спросить "поведение описания объекта" (-O)

Конечно, если вы часто это делаете, вы можете создать свой собственный псевдоним для "expr -l objС++ -O -"

Ответ 2

В Swift вы используете функцию unsafeBitcast для приведения адреса памяти к переменной в lldb.

expr $mv = unsafeBitCast(0x7a66cdb0, MapView.self)

Это приведёт адрес памяти к объекту MapVie. Когда вы создаете свои собственные объекты, вы можете обнаружить, что вам нужно import ваш проектный модуль в lldb.

Обновление для Swift 4: кажется, что синтаксис немного изменяется в Xcode 10.1, поэтому части unsafeBitCast теперь нужно unsafeBitCast имя второму параметру, и мы добавим let (или, возможно, var зависимости). Итак, приведенный выше пример теперь становится

expr let $mv = unsafeBitCast(0x7a66cdb0, to: MapView.self)

Ответ 3

Нет такого пути. Отладка Swift в значительной степени является не стартером. Оценка выражений и проверка переменных при паузе полностью нарушена. Теперь вам лучше использовать println или NSLog.

EDIT Это был год назад. LLDB значительно улучшен для использования с Swift сейчас!

Ответ 4

Версия 6.1.1 (6A2008a) Я отлаживаю иерархию представления. У меня есть собственный подкласс UIImage. Вот как это работает для меня:

(lldb) po 0x7fc6ecb55e30

<Lesson_1_Quartz_Composer.Layer: 0x7fc6ecb55e30; baseClass = UIImageView; frame = (0 0; 320 49.5); opaque = NO; gestureRecognizers = <NSArray: 0x7fc6ecb6df20>; layer = <CALayer: 0x7fc6ecb55f30>>

(lldb) po [0x7fc6ecb55e30 isUserInteractionEnabled]
0x0000000182002001

(lldb) po (bool)[0x7fc6ecb55e30 isUserInteractionEnabled]
true

(lldb)  expr -l objc++ -O -- [(id)0x7fc6ecb55e30 isUserInteractionEnabled]
0x0000000182002001

Очевидно, что это подкласс UIView, поэтому он objective-c, но он смешивается с Swift.