0

我正在尝试访问defaultUserNotificationCenter我的 C++ 应用程序,但似乎无法正常工作。下面的代码导致错误:

[NSUserNotificationCenter defaultUserNotificationCenter]:无法识别的选择器发送到实例 $memory-location-to-notifCenter

在最后一行提出例外。

id notifCenter = (id)objc_getClass("NSUserNotificationCenter");
notifCenter = objc_msgSend(notifCenter, sel_registerName("alloc"));
notifCenter = objc_msgSend(notifCenter, sel_registerName("defaultUserNotificationCenter"));

我在没有allocing的情况下尝试过这个,notifCenter但是即使在我使用或不使用包含 Bundle Identifier 的 Info.plist 文件之前,这也会导致notifCenter为零。...defaultUser...

只是为了确保幕后不会发生任何疯狂的事情,defaultUserNotificationCenter我编写了一个小的 Obj-C 程序来做同样的事情(NSUserNotificationCenter *defNotifCenter = [NSUserNotificationCenter defaultUserNotificationCenter];)并将其加载到 Hopper 以检查程序集,它显示:

    mov  rsi, qword [0x100001128] ;@selector(defaultUserNotificationCenter)
    mov  rdi, qword [objc_cls_ref_NSUserNotificationCenter]
    call imp___stubs__objc_msgSend

这表明系统级别没有任何异常情况发生,所以现在我完全不知所措。

4

1 回答 1

1

如果你调用alloc一个 Objective-C 类,你会得到一个指向该类的新实例的指针。

id notifCenter = (id)objc_getClass("NSUserNotificationCenter");
notifCenter = objc_msgSend(notifCenter, sel_registerName("alloc"));

此时,notifCenter已重新分配给 的新实例NSUserNotificationCenter。它不再是对 Class 实例的引用,也不再有权访问 Class 方法。

notifCenter = objc_msgSend(notifCenter, sel_registerName("defaultUserNotificationCenter"));

现在您正在对该类的实例调用一个方法。您只能在实例上调用实例方法,在 Class 实例上调用类方法。

我认为如果您只删除中间线(带有 的线alloc),这将起作用。

我还认为您应该使用 .mm 文件探索 Objective-C++。使用 Objective-C 本身而不直接驱动运行时非常好。

于 2018-01-01T06:02:54.190 回答