Могут ли сообщения, отправленные объекту в Objective-C, отслеживаться или распечатываться?

Возможный дубликат:
Вызов метода перехвата в Objective-C
Как зарегистрировать все методы, используемые в приложении iOS

Например, UIViewController объект в iOS получает много сообщений, прежде чем его вид будет показан пользователю:

  1. viewWillAppear
  2. viewWillLayoutSubviews
  3. viewDidLayoutSubviews
  4. viewDidAppear
  5. ...

поскольку исходный код фреймворка недоступен для просмотра, мы должны полагаться на книги или блоги или есть способ распечатать или отследить все сообщения, отправленные этому объекту с помощью (1) Objective-C или (2) любым инструментом?

2 ответа

Решение

Вместо моего комментария лучший подход, который я использовал (и до сих пор использую), это вызов:

(void)instrumentObjcMessageSends(YES);

Когда мне нужно начать регистрировать все сообщения, а затем:

(void)instrumentObjcMessageSends(NO);

Не забудьте добавить #import <objc/runtime.h>,
Когда мне это больше не нужно. Раздражает то, что журнал создается под /tmp/msgSends- а это значит, что вам нужно открыть терминал и использовать tail чтобы увидеть это в удобочитаемом виде.

То, что напечатано, выглядит примерно так:

- CustomTableViewController UIViewController _parentModalViewController
- CustomTableViewController UIViewController isPerformingModalTransition
- CustomTableViewController UIViewController setInAnimatedVCTransition:
- CustomTableViewController UIViewController viewWillMoveToWindow:
- CustomTableViewController UIViewController isPerformingModalTransition
- CustomTableViewController UIViewController parentViewController
- CustomTableViewController UIViewController _popoverController
- CustomTableViewController UIViewController _didSelfOrAncestorBeginAppearanceTransition
- CustomTableViewController UIViewController parentViewController
- CustomTableViewController UIViewController __viewWillDisappear:
- CustomTableViewController UIViewController _setViewAppearState:isAnimating:
- CustomTableViewController UIViewController automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers

Примечание. Прошло довольно много времени с тех пор, как я использовал этот подход в последний раз, и похоже, что этот подход не регистрирует частные методы в подклассах. Итак, если у вас есть DummyClass с -(void)_dummyMethod как личное, а затем DummySubClass с -(void)_dummyMethod реализация, сообщение не будет зарегистрировано.

Для iOS это работает только на симуляторе.

Вы можете использовать DTrace для мониторинга работающего приложения, чтобы увидеть вызываемые методы и классы. Вы можете легко контролировать приложение iOS, запущенное в симуляторе, используя DTrace в командной строке. Сначала вам нужно будет найти PID приложения, используя ps и затем вы можете запустить зонд DTrace, как показано ниже:

sudo dtrace -q -n 'objc1234:::entry { printf("%s %s\n", probemod, probefunc); }' 

где 1234 - идентификатор процесса приложения.

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

UIStatusBarItemView -isVisible
UIStatusBarLayoutManager -_positionAfterPlacingItemView:startPosition:
UIView(Geometry) -frame
CALayer -frame
UIStatusBarLayoutManager -_startPosition
UIView(Geometry) -bounds
CALayer -bounds
UIStatusBarItemView -standardPadding
UIStatusBarItem -appearsOnLeft
UIStatusBarItem -leftOrder

Если вы заинтересованы только в отслеживании одного класса, UIView например, вы можете использовать:

sudo dtrace -q -n 'objc1234:UIView::entry { printf("%s %s\n", probemod, probefunc); }'

Если вы хотите отслеживать все звонки на dealloc на всех классах вы бы использовали:

sudo dtrace -q -n 'objc1234::-dealloc:entry { printf("%s %s\n", probemod, probefunc); }'

Очевидно, вы могли бы объединить их, чтобы увидеть только UIViewdeallocs:

sudo dtrace -q -n 'objc1234:UIView:-dealloc:entry { printf("%s %s\n", probemod, probefunc); }'

Если вы хотите иметь возможность различать определенный объект класса, вы также можете напечатать адрес памяти объекта (self) используя следующее:

sudo dtrace -q -n 'objc1234:UIView:-dealloc:entry { printf("%s (0x%p) %s\n", probemod, arg0, probefunc); }'

DTrace очень мощный и может сделать значительно больше, чем я показал здесь.

Другие вопросы по тегам