当前位置:  开发笔记 > 后端 > 正文

在Objective-C类中混合C函数

如何解决《在Objective-C类中混合C函数》经验,为你挑选了4个好方法。

我正在编写一个Objective-C类,但是它使用了用C编写的API.这很好,因为使用Objective-C调用混合C调用几乎没有问题.

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

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

MyCFHostClientCallBackC函数在哪里定义如下:

static void MyCFHostClientCallBack(CFHostRef host, CFHostInfoType typeInfo, const CFStreamError *error, void *info);

    可以/如何使用Objective-C方法代替此方法?

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

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

rjstelling.. 49

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

下载Zip文件(09_MySQLiteTableView.zip)

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

int MyCFunction(int num, void *data)
{
     //code here...
}

@implementation

- (void)MyObjectiveCMethod:(int)number withData:(NSData *)data
{
      //code here
}

@end

因为C函数在外面@implementation它不能调用类似的方法

[self doSomething]

并且无法访问ivars.

只要回调函数采用 通常类型的userInfocontext类型参数,就可以解决这个问题void*.这可用于将任何Objective-C对象发送到C函数.

与示例代码中一样,可以使用常规的Objective-C操作来操作它.

另外请阅读以下答案:在Objective-C类中混合使用C函数



1> rjstelling..:

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

下载Zip文件(09_MySQLiteTableView.zip)

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

int MyCFunction(int num, void *data)
{
     //code here...
}

@implementation

- (void)MyObjectiveCMethod:(int)number withData:(NSData *)data
{
      //code here
}

@end

因为C函数在外面@implementation它不能调用类似的方法

[self doSomething]

并且无法访问ivars.

只要回调函数采用 通常类型的userInfocontext类型参数,就可以解决这个问题void*.这可用于将任何Objective-C对象发送到C函数.

与示例代码中一样,可以使用常规的Objective-C操作来操作它.

另外请阅读以下答案:在Objective-C类中混合使用C函数


C函数不需要在`@ implementation`之外.
实际上,@ implementation块中的C函数具有能够直接访问私有和受保护的ivars的独特属性.因此,根据我自己的经验,在相应的实现中放置"属于"类的C函数变成了一种强有力的习惯.我建议你更新你的答案.
@Bavarious:编译器允许你在`@ implementation`中使用函数,但它仍然不是`@ implementation`的一部分,因为函数不能属于一个类.作为一种风格问题,我把它留在`@ implementation`之外,并推荐其他人做同样的事情,以明确这一点.
为了澄清,如果他们可以访问该类的实例,他们将可以访问私有ivars.例如int MyCFunction(MyClass*self,int num,void*data).当你的-MyObjectiveCMethod:withData:objc-method被编译时,这非常类似于幕后的情况.

2> diciu..:

要从C回调调用Objective-C代码,我会使用类似的东西:

void * refToSelf;
int cCallback()
{
    [refToSelf someMethod:someArg];
}

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


只需添加一个:许多回调允许指定"用户数据"; 在这种情况下,对象指针可以用作用户数据(并且您不再需要全局变量refToSelf).可能是您的回调函数支持信息指针中的"用户数据".
这是错误的实施.它假设您只有一个ComeClass实例.void*refToSelf; 是一个静态/全局变量.每当你[[SomeClass alloc] init]你的refToSelf将被创建的最后一个实例覆盖.cCallback不会调用正确的SomeClass,而是始终创建最后一个.此外 - 它会在最后一次创建的SomeClass被释放时崩溃(至少在上面的代码中),因为在释放SomeClass时你没有清除refToSelf.

3> Peter Hosey..:

可以/如何使用Objective-C方法代替此方法?

你不能.

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

是.编写C函数并将其用作CF函数的回调.

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

您可以在上下文结构中设置selfinfo指针.这将被传递给回调.然后,在回调中,将info指针强制转换为id:

MyClass *self = (id)info;

然后,您可以发送self消息.但是,您仍然无法直接访问实例变量,因为C函数位于该@implementation部分之外.你必须把它们作为属性.您可以使用类扩展来执行此操作.(与该文档所说的相反,您不会在内部声明扩展名@implementation,而是在与其相同的文件中,通常在其上方.)



4> Marc Charbon..:

我总是发现在这种情况下有用的是在C API之上创建一个Obj-C包装器.实现使用C函数所需的内容,并在其上构建一个Objective-C类(或两个),以便外部世界都能看到.例如,在这样的回调的情况下,您可以创建一个C函数,在其他对象上调用Obj-C委托方法.

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有