NSNotificationCenter捕获并跟踪所有NSNotifications [英] NSNotificationCenter trapping and tracing all NSNotifications

查看:113
本文介绍了NSNotificationCenter捕获并跟踪所有NSNotifications的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了更好地理解引擎盖下发生的事情,我希望对我的应用程序中发生的任何通知进行完整的跟踪。

For some better understanding on what happens "under the hood", I would love to do a complete trace of any notifications happening within my application.

Naïve就像我一样,我尝试的第一件事就是这样注册:

Naïve as I am, the first thing I tried was registering like this:

在我的应用中的某个地方:

Somewhere in my app:

{
    [...]
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(traceNotifications:) name:nil object:nil];
    [...]
}

- (void)traceNotifications:(NSNotification *)notification
{
    NSLog(@"received notification %@", [notification name]);
}

我确实收到了一些通知。但在某些时候,应用程序确实崩溃了。堆栈跟踪显示它在realizeClass中与EXC_BAD_ACCESS崩溃,根据我的经验,它确实表明在释放后调用了某些东西。然而,我的观察对象仍然存在,它的解除分配器尚未被调用(尚未)。

I do actually get a number of notifications that way. But at some point the application does crash. The stack trace shows it is crashing with EXC_BAD_ACCESS in realizeClass, which from my experience does indicate that something gets called after its deallocation. My observing object however still is alive, its deallocator has not been called (yet).

接下来我尝试设置断点到 - [ NSNotificationCenter postNotification:] 然后每当我的断点被捕获时,在gdb-console中运行 po {NSNotification *}($ ebp + 16)。这确实揭示了一些通知,但并不是我期望/希望的所有通知。例如,我的应用程序确实正确处理了方向更改,但在重新定位设备时(模拟器中)没有看到任何通知被捕获。

Next thing I tried was setting a breakpoint towards -[NSNotificationCenter postNotification:] and then run po {NSNotification *}($ebp+16) inside the gdb-console whenever my breakpoint is trapped. That did reveal a few notifications but not all that I am expecting/hoping for. For example, my application does handle orientation-changes properly but I do not see any notifications being trapped when reorienting the device (in the simulator).

什么是我错过了?
有没有办法(例如工具)可靠地观察NSNotificationCenter?

感谢任何提示。

推荐答案

我开始工作的唯一解决方案是使用断点。

The only solution I got to work was using breakpoints.

我在 __ CFXNotificationPost_old (CoreFoundation)并将其与调试器命令 po {NSNotification *}($ ebp + 12)捆绑在一起。所有这些在Xcode GUI中都可以实现:

I added a breakpoint at __CFXNotificationPost_old (CoreFoundation) and bundled that with a Debugger Command po {NSNotification *}($ebp+12). All of this is nicely doable within the Xcode GUI:


  • 点击Xcode应用程序菜单上的运行(屏幕顶部)

  • 在Debugger窗口中选择Debugger

  • 点击Show-Breakpoints

  • 点击输入符号名称-line并输入__CFXNotificationPost_old

  • 点击最右侧的+

  • 选择Debugger Command 在该下拉列表中

  • 输入po {NSNotification *}($ ebp + 12)

  • (您可能还想激活日志记录检查底部的Log复选框)

  • 在Xcode中的模拟器调试会话中运行你的应用程序

  • click on "Run" on the Xcode application menu (top of the screen)
  • select "Debugger"
  • within the Debugger window click on "Show-Breakpoints"
  • click on the "Enter Symbol-Name"-line and enter "__CFXNotificationPost_old"
  • click on the "+" on the very right side
  • select "Debugger Command" on that dropdown-list
  • enter "po {NSNotification *}($ebp+12)
  • (you may also want to activate logging by checking the "Log" checkbox at the bottom)
  • run your app in a simulator-debug-session from within Xcode

每当发布NSNotification并将其显​​示在gdb-console中时,应用程序将停止执行。

The app will stop its execution whenever a NSNotification is posted and display it within the gdb-console.

我确实试图在其中创建一个跟踪点gdb但失败了,因为Xcode gdb中的跟踪点操作似乎有问题 - 或者我可能只是太过stoopid而无法使用它们ng。

I did try to create a tracepoint within gdb but failed because the tracepoint actions within Xcode gdb seem to buggy - or maybe I am just too stoopid to get them working.

我也试图创建一个自定义的Instruments Dtrace脚本,但由于我的Dtrace Karate不够强大而失败。

I also tried to create a custom Instruments Dtrace script, but failed as my Dtrace Karate just isnt strong enough.

如果您设法让后面的任何一个选项起作用,请继续将它们作为替代答案发布 - 我将赞成并将其标记为受欢迎的选项。

If you manage to get any of the latter options to work, please go ahead and post them as an alternative answer - I will upvote and mark them as the favored one.

更新

在这个问题之后,我找到了正确的方式来捕获所有通知CoreFoundation级别。

Ages after this question, I found the right way of trapping all notifications on the CoreFoundation level.

这是如何做到的:

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的界面。

I actually feel a little ashamed that I did not look closer at CoreFoundation's interface before.

这篇关于NSNotificationCenter捕获并跟踪所有NSNotifications的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆