标签:style class blog code http tar
昨天遇到一个只有一行错误信息的问题:
-[NSNull objectForKey:]: unrecognized selector sent to instance 0x537e068
由于这个问题发生在次线程,所以没有太有用的堆栈信息,而是只有简单的SIGABRT信息:
考虑到unrecognized selector sent to instance这类问题是由于向某个对象发送了未实现的消息,这个过程大致如下(图片摘自这里):
参考Objective-C的对象模型:
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */消息发送的流程大致如下:
- (id)forwardingTargetForSelector:(SEL)aSelector; - (void)forwardInvocation:(NSInvocation *)anInvocation; - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
我第一反应是添加resolveInstanceMethod:来观察,这是一个类方法,所以得添加到metaClass上:
Class metaClass = objc_getMetaClass("NSNull");
SEL sel = @selector(resolveInstanceMethod:);
const char *type = "c@::";
class_addMethod(metaClass, sel, (IMP)resolveInstanceMethod, type);Class metaClass = objc_getMetaClass("NSNull");
SEL sel = @selector(objectForKey:);
const char *type = "@@:@";
class_addMethod(metaClass, sel, (IMP)objectForKey, type);{
fromId = "\U6d4b\U8bd520#\U65fa\U4f01\U65e0\U7ebf\U6d4b\U8bd5";
msgContent = "<null>";
msgSendTime = 1402909302;
msgType = 12;
uuid = 0;
}原因是由于服务端推送的消息中一个必填字段为空,而客户端也刚好在此处没有使用项目代码中约定的类型检查宏(此处应为VFDict),而是直接当做NSDictionary来操作。
利用objc的runtime来定位次线程中unrecognized selector sent to instance的问题,布布扣,bubuko.com
利用objc的runtime来定位次线程中unrecognized selector sent to instance的问题
标签:style class blog code http tar
原文地址:http://blog.csdn.net/jasonblog/article/details/31768239