在Objective-C类中混合C函数
-
03-07-2019 - |
题
我正在编写一个Objective-C类,但它使用了用C编写的API。这很好,因为使用Objective-C调用混合C调用几乎没有问题。
然而,其中一个API调用需要回调方法(示例):
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方法和函数,这是一个在iPhone App中使用SQLite API的简单示例:(课程网站)
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。
只要回调函数采用 userInfo
或 context
类型参数(通常为 void *
类型),就可以解决此问题。 。这可用于将任何Objective-C对象发送到C函数。
如示例代码,这可以通过正常的Objective-C操作来操作。
另外请阅读以下答案:混合C Objective-C类中的函数
其他提示
要从C回调调用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函数的回调函数。
如何将C函数与Objective-C方法混合使用?
您可以在上下文结构中将 self
设置为 info
指针。这将被传递给回调。然后,在回调中,将 info
指针转换回 id
:
MyClass *self = (id)info;
然后您可以发送 self
消息。但是,您仍然无法直接访问实例变量,因为C函数位于 @implementation
部分之外。你必须把它们作为属性。您可以使用类扩展程序一>。 (与该文档所说的相反,你不会在 @implementation
中声明扩展名,但是在与它相同的文件中,通常在它上面。)
在这种情况下,我总是发现有用的是在C API之上创建一个Obj-C包装器。实现使用C函数所需的内容,并在其上构建一个Objective-C类(或两个),以便外部世界都能看到。例如,在这样的回调的情况下,您可以创建一个C函数,在其他对象上调用Obj-C委托方法。