Objective-C要传递给C函数的选择器指针

Cla*_*dia 16 c pointers function-pointers objective-c

我有一个包含函数指针的C结构.现在,我在C中使用了这个设置没有问题,但现在我在Objective-C中使用这个C结构,我需要传递一个在Objective-C类中定义的函数(或选择器)指针.

1.这是我对Objective-C选择器所需要的,它需要作为指向C函数的指针传递:

- (void)myObjCSelector:(int*)myIntArray
{
    // Do whatever I need with myIntArray
}
Run Code Online (Sandbox Code Playgroud)

2,这里是我碰壁,在Objective-C的我想选择通过作为指针到C函数调用:在地方的" myObjCSelectorPointer "我需要正确的语法通过选择作为这个C函数调用中的函数指针:

passObjCSelectorPointerToCContext(cContextReference, myObjCSelectorPointer);
Run Code Online (Sandbox Code Playgroud)

我确实调查了这个问题,但主要可以找到几种不同的方法来做类似的事情,但我找不到任何特定的调用C函数和传递Objective-C选择器指针.

twe*_*ter 18

在objc中,选择器不是函数指针.选择器是一个唯一的整数,它映射到objc运行时存储的方法查找表中的字符串.在上面的例子中,您的方法名称将是myObjCSelector:并为您输入的唯一选择器@selector(myObjCSelector:).但是这对你没有用,因为它不代表函数的特定实现.

您正在寻找的是IMP.请参阅 SO问题.

编辑2:

 IMP myObjCSelectorPointer = (void (*)(id,SEL,int*))[self methodForSelector:@selector(myObjCSelector:)];
Run Code Online (Sandbox Code Playgroud)

然后你可以使用调用方法

myObjCSelectorPointer(self,@selector(myObjCSelector:),myIntArray);
Run Code Online (Sandbox Code Playgroud)

但是,这意味着您需要确保在c函数调用passObjCSelectorPointerToCContext中添加指向self的指针.所以看起来应该是这样的

passObjCSelectorPointerToCContext(cContextReference, self, myObjCSelectorPointer); 
Run Code Online (Sandbox Code Playgroud)

从包含该方法的对象内部调用时.

值得注意的是,使用IMP几乎从来都不是正确的技术.你应该尝试坚持使用纯粹的Obj-C.在第一次调用消息后,Obj-C非常有效,因为它使用了时间缓存.

编辑1:

理解为什么objc以这种方式工作是有用的.Apple文档对此进行了深入解释.但是简短的解释如下:

当您向某个对象发送消息时,[myobject somemethod]编译器不会立即知道某些方法要调用哪个特定实现,因为可能有多个类具有someomethod的多个覆盖版本.所有这些方法都具有相同的选择器,无论其参数和返回值如何,因此决定在程序运行时哪些方法的实现被定义.[myobject somemethod]由编译器转换为C函数调用:

objc_msgSend(myobject, @selector(somemethod))
Run Code Online (Sandbox Code Playgroud)

这是一个特殊的函数,它搜索每个myobject类布局以查看该类是否知道如何响应somemethod消息.如果没有,则搜索该类的父级,依此类推,直到根.如果没有类可以响应,somemethodNSObject定义一个名为forward的私有方法,其中发送所有未知消息.

假设一个类可以响应该somemethod消息,那么它还将具有IMP类型的特定指针,该指针指向该方法的实际实现.此时将调用该方法.

这个程序比我描述的要多得多,但是大纲应该足以帮助你理解选择器的目标是什么.

最后一点是,方法名称通过@selector指令映射到唯一整数的原因是运行时不必浪费时间进行字符串比较.

  • 哇!你刚刚教我新的有用的东西!谢啦. (2认同)