IsKindOfClass unexplained identity problem

I would have thought it was a person, but it doesn't work for me right now.

Here is my lldb query:

po [self class]

==> MyCustomClass

po [MyCustomClass class]

==> MyCustomClass

po [self class] == [MyCustomClass class]

==> true

p [self isKindOfClass:[MyCustomClass class]]

==> '\ 0' (i.e. false).

The definition of isKindOfClass: "Returns a Boolean value indicating whether the recipient is an instance of this class or an instance of any class that inherits from this class."

What kind of nonsense (my fault or otherwise) can cause this behavior?

Background for those looking after: I'm unfortunately working with a third party API that requires me to pass an object as a void pointer and then return it to the appropriate type. Even though everything compiles very well, at runtime I'm told that the object doesn't recognize the selector I'm trying to send to it. This means (I think?) That this is not an instance of the class that I am casting it to. While trying to test this, I am facing this problem using [NSObject isKindOfClass]

. What's going on here?

Running on iOS 8.1 iPad, build in XCode 6.1.1.

Here is a screenshot of the last test:

lldb screenshot


PROGRESS EDIT: I finally managed to get a breakpoint on the thread this library is running on using this post and I see some even crazier stuff.

given (void*)data

, I get:

po [data class]

==> MyCustomClass

po [data isKindOfClass:[MyCustomClass class]]

==> nil

(again, this just means false)

Obviously, I really broke something. Are there any known issues that can cause something like this?


EDIT SSCCE-ish example : You start with an open C function that gets passed to the background as a callback function:

void libraryCallbackFunction(eventname, stuff, (void*)data)

The library calls this function (from a new thread) when an event occurs, and you use this function to handle the event. data

should be a pointer to whatever old class you want to call from this event handler function. Inside this function, you pass data to any class. Then you can send messages to the data instance on the main thread. Let's call it a view controller:

void libraryCallbackFunction((void*)data) {
   MyCustomClass *myViewController = (__bridge MyCustomClass*)data;

   /* stuff stuff stuff */

   dispatch_async(dispatch_get_main_queue(), ^{
      [myViewController makeInterfaceChange];
   });
}

      

This snippet compiles fine for me, but at runtime I get the error:

NSInvalidArgumentException', reason: '+[MyCustomClass makeInterfaceChange]: unrecognized selector sent to class 0xf3fad8

So it looks like it data

doesn't actually point to an instance of MyCustomClass. Yes, makeInterfaceChange is defined for MyCustomClass, otherwise it won't compile. As I said, the call po [data class]

from lldb is when the breakpoint in this function is issued MyCustomClass

.

Any ideas?


WAIT, MAYBE ?: The critical (__bridge) listing in this part of the code is not syntax highlighting, although it is everywhere in my project . Problem? Or is it just Xcode, being normal, with syntax highlighting as usual? Is there any error that could cause __bridge to fail?

+3


source to share


1 answer


You are registering an object of a class, not an instance that should be passed to your callback. This is indicated +

in the exception message.

The weirdness with isKindOfClass:

happens because it [someClassObject class]

returns itself, not its class (which will be the metaclass object). A class object, however, does not have a kind (it is not a member of the class it represents); they have their own (opaque) hierarchy .



[[NSString class] isKindOfClass:[NSString class]]

      

for example, it produces the same result as that of your code: NO

.

+2


source







All Articles