Ios ObjC类_addMethod不检查参数类型? class\u addMethod函数不检查参数类型 选择器是否只是实现的关键点,而没有其他角色 为什么带有一个参数的IMP可以工作,但有两个参数不行 当调用带有params(或not)但不带params(或has)的IMP的方法时,它是如何工作的
有人能帮我解释一下原因吗 class_addMethod函数不检查参数类型 事实并非如此。作为一种动态类型化语言,Objective-C本质上都是Ios ObjC类_addMethod不检查参数类型? class\u addMethod函数不检查参数类型 选择器是否只是实现的关键点,而没有其他角色 为什么带有一个参数的IMP可以工作,但有两个参数不行 当调用带有params(或not)但不带params(或has)的IMP的方法时,它是如何工作的,ios,objective-c,Ios,Objective C,有人能帮我解释一下原因吗 class_addMethod函数不检查参数类型 事实并非如此。作为一种动态类型化语言,Objective-C本质上都是id在运行时对象的类型检查发生在编译时,并且该信息不会保存在二进制文件中class_addMethod是一个低级运行时函数,因此不包括任何类型检查。这没关系,因为这些运行时函数很少使用,而且只在您确切知道自己在做什么的情况下使用,因此也就知道应该使用什么类型 SEL只是IMP的一个关键点,没有其他角色 SEL是一个选择器,在Objective-C的典型
id
在运行时对象的类型检查发生在编译时,并且该信息不会保存在二进制文件中class_addMethod
是一个低级运行时函数,因此不包括任何类型检查。这没关系,因为这些运行时函数很少使用,而且只在您确切知道自己在做什么的情况下使用,因此也就知道应该使用什么类型
SEL只是IMP的一个关键点,没有其他角色
SEL
是一个选择器,在Objective-C的典型实现中,它是一个位于引擎盖下的字符串objc_msgSend
将此选择器解析为IMP
,这只是一个函数,其主体包含方法的实现
为什么带有1个参数的IMP有效,但2个参数无效
因为您没有向我们展示foo2
的签名,也没有描述到底出了什么问题,所以很难说。但是,由于您似乎没有尝试使用任何参数调用foo2
,因此,结果将不是您想要的结果也就不足为奇了
另外,在添加方法后,您不会返回YES
,而是调用super
的resolveInstanceMethod:
实现。如果该方法恰好返回NO
,则运行时会认为添加该方法无效。成功添加方法后,应返回YES
。(如果没有,则应调用super
的resolveClassMethod:
实现,而不是resolveInstanceMethod:
)
types
参数错误,并且选择器中的参数编号不匹配。首先解决这些问题#import <objc/runtime.h>
@implementation Foo
+ (void)test
{
[Foo performSelector:@selector(foo)];
[Foo performSelector:@selector(foo) withObject:@"works"];
[Foo performSelector:@selector(foo1)];
[Foo performSelector:@selector(foo2)];
}
+ (BOOL)resolveClassMethod:(SEL)sel
{
NSLog(@"resolveClassMethod: %@", NSStringFromSelector(sel));
if (sel == @selector(foo)) {
class_addMethod(objc_getMetaClass("Foo"), sel, (IMP)fooIMP_withoutArgument, "s@#@@@");
return YES;
} else if (sel == @selector(foo1)) {
class_addMethod(objc_getMetaClass("Foo"), sel, (IMP)fooIMP_with1Argument, "Works");
return YES;
} else if (sel == @selector(foo2)) {
class_addMethod(objc_getMetaClass("Foo"), sel, (IMP)fooIMP_with2Arguments, "Not Works");
return YES;
}
return [super resolveClassMethod:sel];
}
void fooIMP_withoutArgument(id self, SEL _cmd)
{
NSLog(@"fooIMP_withoutArgument");
}
void fooIMP_with1Argument(id self, SEL _cmd, id arg)
{
NSLog(@"fooIMP_with1Argument");
}
void fooIMP_with2Arguments(id self, SEL _cmd, id arg1, id arg2)
{
NSLog(@"fooIMP_with2Argument");
}
@end
2018-02-27 16:41:31.638693+0800 Test[74840:2194481] resolveInstanceMethod: foo
2018-02-27 16:41:31.639201+0800 Test[74840:2194481] fooIMP_withoutArgument
2018-02-27 16:41:31.639228+0800 Test[74840:2194481] fooIMP_withoutArgument
2018-02-27 16:41:31.639490+0800 Test[74840:2194481] resolveInstanceMethod: foo1
2018-02-27 16:41:31.639519+0800 Test[74840:2194481] fooIMP_with1Argument
2018-02-27 16:41:31.639548+0800 Test[74840:2194481] resolveInstanceMethod: foo2
(lldb)