我一直在阅读Objective-C块(例如在Apple documentation,a blog post和one或two或three Stack Overflow答案)。我想将C / C ++样式的回调传递给Objective-C方法。
这是我在C / C ++方面的声明
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*CALCULATION_CALLBACK)(int x);
void setCubeCallback(int x, CALCULATION_CALLBACK callback);
#ifdef __cplusplus
}
#endif
并在Objective-C
中@interface IOSPluginTest : NSObject
typedef void (^CalculationHandler)(int x);
-(void)cubeThisNumber:(int)number andCallbackOn:(CalculationHandler)callback;
@end
这是Objective-C实现
#import "IOSPluginTest.h"
@implementation IOSPluginTest
-(void)cubeThisNumber:(int)number andCallbackOn:(CalculationHandler)callback {
int result = number * number * number;
if (callback != nil) {
callback(result);
}
}
@end
最后一点,C / C ++实现出了问题
void setCubeCallback(int x, CALCULATION_CALLBACK callback) {
[[[IOSPluginTest alloc] init] cubeThisNumber:x andCallbackOn:callback];
}
无法使用错误编译
将'CALCULATION_CALLBACK'(又名'void(*)(int)')发送到不兼容类型'CalculationHandler'的参数(又名'void(^)(int)')
这两种类型的描述void(*)(int)
和void(^)(int)
看起来与我很相似;我错过了什么?
答案 0 :(得分:3)
你缺少的是块和函数指针是不同类型的东西。
函数指针几乎就是函数代码第一条指令的地址。
块是一个对象。该对象持有的数据是函数指针,但它也有其他数据。除了作为对象的基本基础结构(例如isa
指针)之外,块可以从其定义站点捕获变量值。
你可以在Objective-C中使用函数指针。如果您希望两个接口直接兼容,只需使用CALCULATION_CALLBACK
作为Objective-C方法中callback
参数的类型。
或者,您可以将函数指针包装在一个块中,如下所示:
void setCubeCallback(int x, CALCULATION_CALLBACK callback) {
[[[IOSPluginTest alloc] init] cubeThisNumber:x andCallbackOn:^(int result){ callback(result); }];
}
答案 1 :(得分:1)
void(*)(int)
是一个方法指针void(^)(int)
一个块,在其他语言中称为闭包。它们根本不同。虽然方法指针只是这样做 - 指向一个方法 - ,但块也通过封装来传输数据。这个事情是非常不同的,尝试将它们从一个投射到另一个是没有意义的。
但是你可以在Objective-C中使用C方法指针。