2016-03-23 64 views
-2

今天,我正在从C++到Objective-c方法的回调传递。
最后,我解决了这个问题,但是有一些代码让我困惑。
在Objective-C,人们日常使用的块来实现回调,块声明如下:'void(*)(int)'与'void(^)(int)'相同吗?

返回类型(^块名称)(parameterTypes)

我也了解C++的回调,这样定义的相同类型的回调:

返回类型(*了funcName)(parameterTypes)

当我路过一个回调从C++到Objective-C编译器警告我:

 
"Cannot initialize a parameter of type 'void (^)(int)' with an rvalue of type 'void (*)(int)" 

最后,我改变^*,它的工作原理。我想知道,定义中^*之间有什么区别,是否具有相同的行为?

+2

在C++'^'是按位异或 – DimChtz

+0

@DimChtz只是因为它是在Objective-C的。上下文有所不同。 – trojanfoe

回答

2

这是块:

returnType (^blockName)(parameterTypes) 

这是一个函数指针:

returnType (*funcName)(parameterTypes) 

他们是不兼容的。

+0

我想知道的是运行时行为的差异 – DelphiQin

+0

@DelphiQin你没有问过,但是有大量关于这两个概念的在线文档。 – trojanfoe

1

标准C和C++没有可调用的块。然而,显然,这些语言的一些编译器确实将该特性作为扩展来实现。我看到的一些文档表明它也是Objective C的一个Apple扩展,但是因为Objective C在Apple世界之外很少使用,所以这可能是没有区别的区别。

在任何一种语言,如果你实现一个回调的功能,那么你必须通过一个函数指针呈现回调到预期的来电者,并调用者必须准备接受它的这种形式。在另一方面,如果你实现一个回调作为一个块,那么你必须将其通过块指针呈现给调用者,调用者必须准备接受形式。这两者不可互换,并且它们具有不同的语法,您已经介绍过。设计一种机制可以接受这两种形式,然而,通过单独的参数或完全分开的注册功能是可能的。

+0

感谢您的回答,它帮助了我。 :) – DelphiQin

1

Objective-C块(^)与函数指针(*)不兼容。
比起函数指针,它们具有能够从周围的背景下捕捉值和变量的利益(他们是关闭)。

这是很容易编写调用从块函数指针的包装:

typedef int (*funptr)(int); 
typedef int (^funblock)(int); 


int use_block_callback(int y, funblock fb) 
{ 
    return fb(y); 
} 

int use_funptr_callback(int y, funptr f) 
{ 
    return use_block_callback(y,^int (int x) { return f(x); }); 
} 

int add_one(int x) { return x + 1; } 

int foo(int x) 
{ 
    return use_funptr_callback(23, add_one); 
} 

// Or 
int (*some_pointer)(int) = add_one; 
int (^some_block)(int) =^int (int x) { return some_pointer(x); } 

"Programming with Objective-C" about blocks.

+0

感谢您的回答,它帮助了我。 :) – DelphiQin

相关问题