Как получить параметры, используя символические контрольные точки в Objective-C

У меня есть точка останова, которая выглядит так

-[UITableViewCell setSelected:]

и это работает, но я не могу понять, как получить значение, которое передается.

я пытался -[UITableViewCell setSelected:(BOOL)what] а также -[UITableViewCell setSelected:what] которые не работают вообще.

Как я могу получить доступ к параметрам?

Если это не сработает, мне придется сделать DebugUITableViewCell просто чтобы посмотреть, что происходит, это хлопотно и затрагивает много кода.

7 ответов

Решение

Если вы отлаживаете свой код на устройстве, параметры при достижении точки останова будут последовательно находиться в регистрах r0, r1 и r2. Если вы используете po $r0 вы увидите объект, получающий setSelected. Если вы используете po $r1 вы получите "описание Objective-C недоступно", потому что это селектор. Осмотрите $r2, чтобы увидеть, установлено ли выбрано значение ДА или НЕТ. Это похожая история на i386, но я не могу вспомнить, какие регистры используются.

В LLDB на симуляторе используют

p $arg3

для первого параметра.

Вы могли бы заменить -[UITableViewCell setSelected:] с вашей собственной реализацией для целей отладки. Ниже, UITableViewCellSetSelected будет вызываться вместо метода UIKit.

static void (*__originalUITableViewCellSetSelected)( UITableViewCell *, SEL, BOOL ) ;
static void UITableViewCellSetSelected( UITableViewCell * self, SEL _cmd, BOOL b )
{
    // your code here... (or set a breakpoint here)
    NSLog(@"%@<%p> b=%s\n", [ self class ], self, b ? "YES" : "NO" ) ;

    (*__originalUITableViewCellSetSelected)( self, _cmd, b ) ; // call original implementation:
}

@implementation UITableViewCell (DebugIt)

+(void)load
{
    Method m = class_getInstanceMethod( [ self class ], @selector( setSelected: ) ) ;
    __originalUITableViewCellSetSelected = (void(*)(id, SEL, BOOL))method_getImplementation( m ) ;
    method_setImplementation( m, (IMP)UITableViewCellSetSelected ) ;
}

@end

Для методов без исходного кода работает следующее: Поместите символическую точку останова, чтобы отладчик останавливался на первой строке метода. Убедитесь, что выбран верхний фрейм стека. Потом:

В методах Objectice-C

  • po $arg1 печатает себя
  • po $arg3 печатает первый аргумент, остальные аргументы в $arg4, $arg5, так далее.

В функциях C аргументы начинаются с $arg1

Это работает как на устройстве IOS, так и на симуляторе.

На основе -[UIApplication sendAction:toTarget:fromSender:forEvent:] Символом мы можем добавить символическую точку останова, чтобы проверить, какой отправитель отправил действие какой цели.

Мы создаем символическую точку останова с помощью:

  • условное обозначение: -[UIApplication sendAction:toTarget:fromSender:forEvent:]
  • Действия командной строки отладчика:
    • po "Target"
    • po $arg4
    • po "Sender"
    • po $arg5

Выход будет: "Target" <project.TargetViewController: 0x14ddb1470> "Sender" <UIButton: 0x14de86000; frame = (331 7; 49 30); opaque = NO; layer = <CALayer: 0x174237020>>

Как сказал @Dan, параметры метода начинаются с аргумента 3 (po $arg3).

вы можете использовать команду lldb:

"поиск изображения -rn ключевое слово"

ключевое слово соответствует функциям, которые вы хотите найти, например, показать

затем вы будете выглядеть следующим образом:

Резюме: Закрытие ApplSlate # 2 (__C.UIBarButtonItem) -> () в ApplSlate.BaseTableViewController.showLoading(includeTabBar: Swift.Bool) -> () в BaseTableViewController.swift:98 Адрес: FullSlate[0x0000000100154a60] (FullSlate.__TEXT.__текст + 1378752)

И вы получаете символическое имя: closure #2 (__C.UIBarButtonItem) -> () in ApplSlate.BaseTableViewController.showLoading(includeTabBar: Swift.Bool) -> ()

Отвечать

XCodeполучить ObjCпервый параметр: $arg3

->

  • lldbвывести значение первого параметра: po $arg3
  • XCode добавить условие символической точки останова: все еще использовать arg3
    • например
      • Условие: (BOOL)($arg3 == NULL)

Связанный

  • остаточный параметр: $arg4, $arg5, ...
  • $arg0не существует
    • например
                (lldb) po $arg0
      error: <user expression 3>:1:1: use of undeclared identifier '$arg0'
      $arg0
      ^
      
  • $arg1это тип функции
    • -означает Instance
      • например
                    (lldb) po $arg1
        _
        
    • +означает Class
  • $arg2является указателем на функцию, используйте SELможет анализировать имя функции
    • например
                (lldb) po $arg2
      8203662366
      
      (lldb) po (SEL)$arg2
      "stringByAppendingString:"
      
Другие вопросы по тегам