在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);
- 可以/我如何调用Objective-C方法代替这个?
- 可以/应该将C函数与我的Objective-C调用混合吗?
- 如何将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函数采用userInfo
或context
types参数(通常是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委托方法。