我的Objective-C
项目中有iOS
个类,它在同一个类中实现Objective-C
和C
代码。我将扩展名更改为.mm
,这部分进展顺利。现在我想设置一个C
方法,该方法将在同一个类中调用Objective-C
方法。我得到的问题是当我尝试从self
方法调用C
时。
这是代码:
void SetNotificationListeners(){
[self fireSpeechRecognition];
}
错误是:
Use of undeclared identifier 'self'
我该如何管理?
答案 0 :(得分:12)
您必须将实例指针传递给C函数:
void SetNotificationListeners(void *uData)
{
MyClass *obj = (__bridge MyClass *)(uData);
[obj fireSpeechRecognition];
}
- (void)myMethod
{
// Call C function from Objective-C method:
myFunction((__bridge void *)(self));
}
(" brigde"只有在使用ARC编译时才需要。)
答案 1 :(得分:2)
将self作为函数调用的参数:
void SetNotificationListeners(void *myObj){
[(MyClass*)myObj fireSpeechRecognition];
}
//in objC
SetNotificationListeners(self);
或者有一个包含引用的全局变量
//global variable
static MyClass *myObj;
//in obj c
myObj = self;
SetNotificationListeners(); //use myObj instead of self in function
在我看来,第一个更好。
答案 2 :(得分:2)
您不必更改文件扩展名。 Objective-C是C的超集,这意味着您可以根据需要在Objective-C文件中使用plain C.
当您编写Objective-C方法的实现时,该方法总是在某个特定实例的上下文中执行,即self
部分。您可以自动地在Objective-C方法中获得self
,但在幕后它只是作为参数传递给方法,请参阅obc_msgsend
。
你的普通C函数不是类的一部分(普通的C函数永远不会),因此当你调用它时没有与之关联的实例,没有隐式的self
。如果希望函数调用某个实例,则必须明确地将指针传递给该实例。例如,一些普通的C API有一个“上下文”指针,你可以在注册回调时传递它。有关此示例,请参阅相邻答案。
答案 3 :(得分:1)
在Objective-C方法中,有两个参数隐式传递到每个方法,即self
和_cmd
。这就是您可以从方法中访问self
的原因。
从Objective-C方法调用时,你可以将self
作为参数传递给你的c函数,但是这个简单的例子我不知道为什么你不会只使用一个方法。
除非您使用的是Objective-C ++,否则无需将文件扩展名更改为.mm