在Objective-C类中混合使用C函数

我正在编写一个Objective-C类,但是它使用了用C语言编写的API。将C调用与Objective-C调用混合导致几乎没有问题,这大体上是好的。

但是,其中一个API调用需要callback方法(示例):

success = CFHostSetClient(host, MyCFHostClientCallBack, &context); 

其中MyCFHostClientCallBack是这样定义的C函数:

 static void MyCFHostClientCallBack(CFHostRef host, CFHostInfoType typeInfo, const CFStreamError *error, void *info); 
  1. 可以/我如何调用Objective-C方法代替这个?
  2. 可以/应该将C函数与我的Objective-C调用混合吗?
  3. 如何将C函数与Objective-C方法混合?

混合C和Objective-C的方法和function是可能的,下面是一个简单的例子,在iPhone应用程序中使用SQLite API 🙁 课程网站 )

下载Zip文件(09_MySQLiteTableView.zip)

C函数需要在Objective-C(.m)文件的@implementation之外声明。

 int MyCFunction(int num, void *data) { //code here... } @implementation - (void)MyObjectiveCMethod:(int)number withData:(NSData *)data { //code here } @end 

因为C函数在@implementation之外,所以不能调用类似的方法

 [self doSomething] 

并无法访问ivars。

只要callback函数采用userInfocontexttypes参数(通常是void*types),就可以解决这个问题。 这可以用来将任何Objective-C对象发送给C函数。

和示例代码一样 ,这可以通过正常的Objective-C操作来操作。

另外请阅读这个答案: 在Objective-C类中混合C函数

要从Ccallback中调用Objective-C代码,我会使用类似于:

 void * refToSelf; int cCallback() { [refToSelf someMethod:someArg]; } @implementation SomeClass - (id) init { self = [super init]; refToSelf = self; } - (void) someMethod:(int) someArg { } 

可以/我如何调用Objective-C方法代替这个?

你不能。

可以/应该将C函数与我的Objective-C调用混合吗?

是。 写一个C函数,并用它作为CF函数的callback函数。

如何将C函数与Objective-C方法混合?

您可以将self设置为上下文结构中的info指针。 这将传递给callback。 然后,在callback中,将info指针转换回id

 MyClass *self = (id)info; 

然后你可以发送self消息。 不过,你仍然不能直接访问实例variables,因为C函数在@implementation部分之外。 你将不得不使他们的财产。 你可以用类扩展来做到这一点。 (与文档说的相反,你不会在@implementation声明扩展名,但是在与它相同的文件中,通常在它的正上方)。

我总是发现在这种情况下有帮助的是在C API上创build一个Obj-C包装器。 实现你所需要的使用C函数,并且在它上面build立一个Objective-C类(或者两个),这样所有的外部世界都会看到。 例如,在像这样的callback的情况下,您可能会创build一个C函数,在其他对象上调用Obj-C委托方法。