Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios ObjC类_addMethod不检查参数类型? class\u addMethod函数不检查参数类型 选择器是否只是实现的关键点,而没有其他角色 为什么带有一个参数的IMP可以工作,但有两个参数不行 当调用带有params(或not)但不带params(或has)的IMP的方法时,它是如何工作的_Ios_Objective C - Fatal编程技术网

Ios ObjC类_addMethod不检查参数类型? class\u addMethod函数不检查参数类型 选择器是否只是实现的关键点,而没有其他角色 为什么带有一个参数的IMP可以工作,但有两个参数不行 当调用带有params(或not)但不带params(或has)的IMP的方法时,它是如何工作的

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的典型

有人能帮我解释一下原因吗

class_addMethod函数不检查参数类型

事实并非如此。作为一种动态类型化语言,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:

  • 不,在运行时通常不进行参数类型检查
  • 选择器只是方法的名称。它仅由一个常量C字符串表示。如果将方法添加到类中,选择器就像字典中的键一样,以实现作为值
  • 添加具有任意数量参数的方法效果良好。您的示例可能会失败,因为
    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)