我正在编写一个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);
  1. 可以/如何使用Objective-C方法代替此?
  2. 可以/我应该将C函数与Objective-C调用混合使用吗?
  3. 如何将C函数与Objective-C方法混合使用?
有帮助吗?

解决方案

可以混合C和Objective-C方法和函数,这是一个在iPhone App中使用SQLite API的简单示例:(课程网站

  

下载 Zip文件(09_MySQLiteTableView。拉链)

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委托方法。

scroll top