我本以为这是一个身份,但现在看来对我来说似乎并不起作用。
看我的lldb提示:po [self class]
==> MyCustomClasspo [MyCustomClass class]
==> MyCustomClasspo [self class] == [MyCustomClass class]
==>是p [self isKindOfClass:[MyCustomClass class]]
==>'\ 0'(即false)。
isKindOfClass的定义:“返回一个布尔值,该值指示接收方是给定类的实例还是从该类继承的任何类的实例。”
哪种废话(我的错或以其他方式)可能导致这种行为?
那些关心这些对象的背景:很遗憾,我正在使用第三方API,该API需要我将对象作为空指针传递,然后将其转换回正确的类型。尽管事实证明一切都可以编译,但在运行时仍被告知该对象无法识别要发送给它的选择器。这意味着(我认为?)它实际上不是我要强制转换为的类的实例。在尝试测试时,我遇到了[NSObject isKindOfClass]
这个问题。这到底是怎么回事?
在XCode 6.1.1中构建的iOS 8.1 iPad上运行。
这是最后一个测试的屏幕截图:
进度编辑:我终于设法使用this post在该库运行的线程中获得了一个断点,并且看到了一些更疯狂的东西。
给定(void*)data
,我得到:po [data class]
==> MyCustomClass
po [data isKindOfClass:[MyCustomClass class]]
==> nil
(再次,这只是表示错误)
显然,我在这里确实弄坏了一些东西。是否有任何已知的问题可能导致这种情况?
编辑 SSCCE样例:从一个裸C函数开始,该C函数作为回调函数传递给背景库:void libraryCallbackFunction(eventname, stuff, (void*)data)
事件发生时,库(从新线程)调用此函数,您可以使用此函数来处理事件。 data
应该是指向您要从此事件处理函数调用的任何旧类的指针。在此函数内,您可以将数据转换为所需的任何类。然后,您可以将消息发送到主线程上的数据实例。我们称之为视图控制器:
void libraryCallbackFunction((void*)data) {
MyCustomClass *myViewController = (__bridge MyCustomClass*)data;
/* stuff stuff stuff */
dispatch_async(dispatch_get_main_queue(), ^{
[myViewController makeInterfaceChange];
});
}
这个代码片段对我来说编译就很好,但是在运行时我遇到了一个错误:
NSInvalidArgumentException', reason: '+[MyCustomClass makeInterfaceChange]: unrecognized selector sent to class 0xf3fad8
因此,换句话说,似乎
data
实际上并未指向MyCustomClass的实例。是的,makeInterfaceChange是为MyCustomClass定义的,否则它将无法编译。如前所述,在此函数中的断点处从lldb调用po [data class]
会得到MyCustomClass
。有任何想法吗?
等待,可能吗?:代码的这一部分中的关键(__bridge)并不是语法高亮显示,即使在我的项目中其他位置也是如此。问题?还是像往常一样,XCode对语法突出显示有些挑剔?是否有任何可能导致__bridge无法正常工作的骨头错误?
最佳答案
您正在注册要传递给回调的类对象,而不是实例。这由异常消息中的+
指示。
之所以会出现isKindOfClass:
怪异,是因为[someClassObject class]
返回自身而不是其类(可能是元类对象)。但是,类对象不是自己的种类(不是它表示的类的成员); they have their own (opaque) hierarchy。
[[NSString class] isKindOfClass:[NSString class]]
例如,产生与您的代码相同的结果:
NO
。关于ios - isKindOfClass莫名其妙的身份问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27551963/