ios - C功能指针到SEL

标签 ios pointers selector objective-c-runtime

我一直在寻找这个好几个小时。

好像以前没有被问过。

有谁知道如何将指向Objective-C方法的C函数指针转换为SEL类型(@selector)?

更新:

我只是在玩运行时:

Method method = class_getInstanceMethod([self class], @selector(test:));
IMP objectMethod = method_getImplementation(method);
objectMethod(self, @selector(<???>), [self superclass]);

我以某种方式开始记得从某处读到SEL(@selector)只是一个指针。所以出于好奇,我想,如果我可以设置一个指向Objective-C方法的指针,我可以用这个指向函数的指针替换(SEL)@selector(),因为它们都是指针吗?

最佳答案

@selector不是方法,它是一个选择器,它可以帮助Objective C运行时选择一个方法。 Objective C中的方法是具有至少两个参数的C函数,它们是必需的:id self,它表示对象; SEL selector,它表示用于调用该函数的选择器。如果使用更多参数定义了方法,则它们将紧随两个必需参数之后。此功能称为IMP实现。每个Objective C方法都有一个后缀IMP
IMP的定义如下:

typedef id (*IMP)(id, SEL, ...);

如果您具有C函数,并且具有正确的参数布局,则可以将该函数分配给现有的或全新的方法,并作为实例或类方法添加到类中。如果您的C函数没有必需的参数布局,则说明正在崩溃。确保C函数正确。

因此,让我们假设使用C函数:
void func_name(id self, SEL sel, NSUInteger x)
{
    NSLog(@"I was called on object %@ with selector %@ and argument %lu", self, NSStringFromSelector(sel), x);
}

并希望将其分配给-[NSObject myNewMethodWithUnsignedInteger:],您可以使用运行时来这样做:
class_addMethod([NSObject class], @selector(myNewMethodWithUnsignedInteger:), (IMP)func_name, [NSString stringWithFormat:@"v@:%s", @encode(NSUInteger)]);

确保阅读class_addMethod here的文档。

如果您的C函数不是必需的格式,则可以使用imp_implementationWithBlock将函数的调用包装在一个块中。

因此,假设您具有以下功能:
void nonCompliantFunc(NSUInteger x)
{
    NSLog(@"Can't touch this!");
}

您可以像这样添加它:
IMP imp = imp_implementationWithBlock(^ (id self, NSUInteger x) { nonCompliantFunc(x); };
class_addMethod([NSObject class], @selector(myNewMethodWithUnsignedInteger:), imp, [NSString stringWithFormat:@"v@:%s", @encode(NSUInteger)]);

您应该检查class_addMethod的返回值,以确保成功添加了该方法。

为了回答您的更新,选择器是指针,但它们是方法表中的指针。加载运行时时,将收集所有选择器,并构建一个表。然后,在加载每个类时,将建立一个方法表,配对选择器和实现。这要复杂得多,但这是要点。

您正在考虑的指针是使用method_getImplementation()获得的指针,但是您不能传递该指针而不是选择器。

关于ios - C功能指针到SEL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22570842/

相关文章:

ios - 如何允许用户每 "n"秒刷新一次表?

ios - 如何在 UINavigationController 的 View 下为 UIView 设置动画

c - 指针未给出预期结果

c - 仅使用指针来打印数组的内容

javascript - 如何在 null 上设置颜色输入的值

ios - 一个类应该在内部处理它自己的数据吗?

ios - 如何使用 FBTestSession 设置 FBPLISTAppIDKey 和 FBPLISTAppSecretKey

时间:2019-03-17 标签:c++segfault: char pointers

iphone - 动态声明函数名?

javascript - 原型(prototype) 1.6.0+ 相当于 'document.getElementsByClassName' 是什么?