Единственное решение, которое я получил, - использование точек останова.
Я добавил точку останова на __CFXNotificationPost_old
(CoreFoundation) и связал ее с командой отладчика po {NSNotification *}($ebp+12)
. Все это хорошо выполнимо в графическом интерфейсе Xcode:
- нажмите «Выполнить» в меню приложения Xcode (вверху экрана)
- выберите «Отладчик»
- в окне отладчика нажмите «Показать точки останова»
- нажмите на строку «Ввести имя символа» и введите «__CFXNotificationPost_old»
- нажмите на "+" на самой правой стороне
- выберите «Команда отладчика» в этом выпадающем списке
- введите "po {NSNotification *} ($ ebp + 12)
- (вы также можете активировать ведение журнала, установив флажок «Журнал» внизу)
- запустить ваше приложение в сеансе отладки симулятора из Xcode
Приложение останавливает свое выполнение при каждом опубликовании NSNotification и отображает его в консоли gdb.
Я пытался создать точку трассировки в GDB, но не смог, потому что действия трассировки в GCD XCode, кажется, глючат - или, возможно, я просто слишком тупой, чтобы заставить их работать.
Я также пытался создать собственный скрипт Dtrace Instruments, но потерпел неудачу, так как мое Dtrace Karate просто недостаточно сильное.
Если вам удастся заставить работать любой из последних вариантов, пожалуйста, отправьте их в качестве альтернативного ответа - я буду голосовать и отмечать их как предпочтительный.
UPDATE
Спустя годы после этого вопроса я нашел правильный способ перехвата всех уведомлений на уровне CoreFoundation.
Вот как это можно сделать:
void MyCallBack (CFNotificationCenterRef center,
void *observer,
CFStringRef name,
const void *object,
CFDictionaryRef userInfo)
{
NSLog(@"name: %@", name);
NSLog(@"userinfo: %@", userInfo);
}
CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(),
NULL,
MyCallBack,
NULL,
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
Мне на самом деле немного стыдно, что я раньше не обращал внимания на интерфейс CoreFoundation.