defaultUserNotificationCenter causing 'unrecognized selector' error in C++

132 Views Asked by At

I am trying to access defaultUserNotificationCenter in my C++ application and I cannot seem to get this working. The code below is causing the error:

[NSUserNotificationCenter defaultUserNotificationCenter]: unrecognized selector sent to instance $memory-location-to-notifCenter

with the exception being raised at the last line.

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

I have tried this without allocing notifCenter however this causes notifCenter to be nil even before I get to ...defaultUser... with or without an Info.plist file containing a Bundle Identifier.

Just to make sure nothing crazy happens behind the scenes with defaultUserNotificationCenter I wrote a small Obj-C program to do the same (NSUserNotificationCenter *defNotifCenter = [NSUserNotificationCenter defaultUserNotificationCenter];) and loaded it up in Hopper to check the assembly and it showed:

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

This shows nothing out of the ordinary happening at the system level so now I am at a complete loss.

1

There are 1 best solutions below

1
On BEST ANSWER

If you call alloc on an Objective-C class, you'll get back a pointer to a new instance of that class.

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

At this point, notifCenter has been reassigned to a new instance of NSUserNotificationCenter. It is no longer a reference to the Class instance and no longer has access to the Class methods.

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

Now you're calling a class method on an instance of that class. You can only call instance methods on an instance, and class methods on a Class instance.

I think that this will work if you just remove the middle line (the line with alloc).

I also think you should explore Objective-C++, using .mm files. It's pretty nice to use Objective-C itself and not directly drive the runtime.