[英]Under what conditions might instancesRespondToSelector: return true, but performSelector: throw an exception
我有一个分布在库中的代码,如下所示:
if ([[NSString class] instancesRespondToSelector: @selector(JSONValue)]) {
NSString *jsonString = [[[NSString alloc] initWithData: jsonData encoding: NSUTF8StringEncoding] autorelease];
dict = [jsonString performSelector: @selector(JSONValue)];
}
由于某种原因-[__NSCFString JSONValue]: unrecognized selector sent to instance
调用performSelector:
方法时, -[__NSCFString JSONValue]: unrecognized selector sent to instance
异常的-[__NSCFString JSONValue]: unrecognized selector sent to instance
被抛出。 这是在我编写的库中分发的代码,但我自己无法重现或调试它。 相反,第三方报告此问题。 在什么条件下, instancesRespondToSelector:
实际上使用performSelector:
调用方法performSelector:
抛出异常?
编辑有一个案例可以解释为什么会发生这种情况,但它没有意义。 如果开发人员要做这样的事情:
@implementation NSString (OurHappyCategory)
+ (BOOL)instancesRespondToSelector:(SEL)aSelector
{
return YES;
}
@end
它可以解释为什么代码正在执行,但它当然是一件非常糟糕的事情。 有没有办法解决这个问题?
NSString基本上是一个类集群 ,并带来各种复杂性......你实际上需要询问实例它是否响应选择器。
NSString *jsonString = [[[NSString alloc] initWithData: jsonData encoding: NSUTF8StringEncoding] autorelease];
if ([jsonString respondsToSelector: @selector(JSONValue)]) {
dict = [jsonString performSelector: @selector(JSONValue)];
}
但是你的问题可能与编译或链接扩展有关...如果在库中添加了类别,那么你需要在-ObjC
链接器标志中撒上。
编辑:
我一直在努力重现这个问题...我无法...你还有更多的信息......例如,故障只发生在模拟器上,或者只是在设备上,iOS 4.x ,GNU链接器与LLDB的链接器,ABI /运行时差异?
我猜你没有以正确的方式导入第三方库。 通常这个方法被添加为NSString的类别,在我看来我可以看到.h文件但是.m没有被编译。 你可以在xcode目标 - >构建阶段 - >编译源代码中检查它。 或者检查你是否在Project - > Build Settings - > Other linker flag = -all_load
输入了这个标志
该异常不直接来自Objective-C运行时,以响应发送实例无法识别的消息。 它来自-[NSObject doesNotRecognizeSelector:]
,它在各种方法查找和转发机制结束时调用。
但是,任何东西都可以调用-doesNotRecognizeSelector:
何时需要。 一个类可以通过覆盖它来“拒绝”一个继承的方法,并使覆盖只是调用-doesNotRecognizeSelector:
. 如文档所述 ,尽管-respondsToSelector:
和+instancesRespondToSelector:
-respondsToSelector:
返回YES
,这将导致您看到的异常。
我无法告诉你为什么__NSCFString
在最终用户的情况下这样做。 使用您的库的应用程序是否使用类别或方法调整以修改该类的方法?
此外,您的日志记录是否显示异常中的实际堆栈跟踪捕获? 这可能是提供信息的。
有一种奇怪的可能性:可能是performSelector
本身以某种方式在不同的链接加载环境中执行,而不是其他代码。 但不完全(或甚至大致)确定如何发生这种情况。
确保没有人在调整功能
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.