This question already has an answer here:
这个问题已经有了答案:
- Pass instance method as function pointer to C Library 1 answer
- 将实例方法作为函数指针传递给C库1
- How do I give C function a pointer to 'self' (calling obj) in objective-c? 2 answers
- 如何在objective-c中给C函数一个指向" self "(调用obj)的指针?2答案
I have Objective-C
class in my iOS
project that implements Objective-C
and C
code in the same class. I changed the extension to .mm
and this part goes well. Now I want to set a C
method that will call the Objective-C
method in the same class. The problem I get is when I am trying to call self
from the C
method. Here is the code :
我的iOS项目中有一个Objective-C类,它在同一个类中实现Objective-C和C代码。我把分机改成了。mm,这部分没问题。现在我想设置一个C方法,它会在同一个类中调用Objective-C方法。我遇到的问题是当我试图从C方法调用self时。这里是代码:
void SetNotificationListeners(){
[self fireSpeechRecognition];
}
the error is :
错误的是:
Use of undeclared identifier 'self'
how can I manage this?
我该怎么做呢?
4 个解决方案
#1
10
You have to pass the instance pointer to the C function:
您必须将实例指针传递给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));
}
(The "brigde" stuff is needed only if you compile with ARC.)
(只有使用ARC编译时才需要“brigde”内容。)
#2
2
You don’t have to change the file extension. Objective-C is a superset of C, which means you can use plain C in your Objective-C files as you please.
您不需要更改文件扩展名。Objective-C是C的超集,这意味着您可以在Objective-C文件中使用简单的C。
When you write an implementation of an Objective-C method, that method always executes in context of some particular instance, that’s the self
part. You get the self
in an Objective-C method automagically, but behind the scenes it’s just passed as an argument to the method, see obc_msgsend
.
当您编写一个Objective-C方法的实现时,该方法总是在某个特定实例的上下文中执行,这就是self部分。你可以在Objective-C方法中自动获得self,但是在幕后它只是作为一个参数传递给这个方法,请参见obc_msgsend。
Your plain C function is not a part of the class (plain C functions never are), therefore there’s no instance associated with it when you call it, there’s no implicit self
. If you want the function to call some instance, you have to pass the pointer to that instance explicitly. For example some of the plain C APIs have a “context” pointer you can pass when registering for a callback. See the neighboring answers for examples of this.
普通C函数不是类的一部分(普通C函数从来都不是),因此在调用它时没有实例关联,没有隐式self。如果希望函数调用某个实例,则必须显式地将指针传递到该实例。例如,一些普通的C api有一个“上下文”指针,您可以在注册回调时传递它。请参见邻近的答案以获得相关示例。
#3
1
Either give self as an argument to the function call:
要么将self作为函数调用的参数:
void SetNotificationListeners(void *myObj){
[(MyClass*)myObj fireSpeechRecognition];
}
//in objC
SetNotificationListeners(self);
or have a global variable that holds reference
或者拥有一个包含引用的全局变量
//global variable
static MyClass *myObj;
//in obj c
myObj = self;
SetNotificationListeners(); //use myObj instead of self in function
The first is better in my opinion.
我认为第一个更好。
#4
1
In Objective-C methods there are two parameters that are implicitly passed into each method, which are self
and _cmd
. This is why you can access self
from within a method.
在Objective-C方法中,有两个参数隐式地传递给每个方法,即self和_cmd。这就是为什么您可以从一个方法中访问self。
You could just pass self
as an argument to your c function when calling from an Objective-C method, but with that trivial example I'm not sure why you wouldn't just use a method.
当调用Objective-C方法时,你可以将self作为参数传递给你的c函数,但是有了这个小例子,我不确定你为什么不只是使用一个方法。
You do not need to change the file extension to .mm
unless you are using Objective-C++
除非使用objective - c++,否则不需要将文件扩展名更改为.mm
#1
10
You have to pass the instance pointer to the C function:
您必须将实例指针传递给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));
}
(The "brigde" stuff is needed only if you compile with ARC.)
(只有使用ARC编译时才需要“brigde”内容。)
#2
2
You don’t have to change the file extension. Objective-C is a superset of C, which means you can use plain C in your Objective-C files as you please.
您不需要更改文件扩展名。Objective-C是C的超集,这意味着您可以在Objective-C文件中使用简单的C。
When you write an implementation of an Objective-C method, that method always executes in context of some particular instance, that’s the self
part. You get the self
in an Objective-C method automagically, but behind the scenes it’s just passed as an argument to the method, see obc_msgsend
.
当您编写一个Objective-C方法的实现时,该方法总是在某个特定实例的上下文中执行,这就是self部分。你可以在Objective-C方法中自动获得self,但是在幕后它只是作为一个参数传递给这个方法,请参见obc_msgsend。
Your plain C function is not a part of the class (plain C functions never are), therefore there’s no instance associated with it when you call it, there’s no implicit self
. If you want the function to call some instance, you have to pass the pointer to that instance explicitly. For example some of the plain C APIs have a “context” pointer you can pass when registering for a callback. See the neighboring answers for examples of this.
普通C函数不是类的一部分(普通C函数从来都不是),因此在调用它时没有实例关联,没有隐式self。如果希望函数调用某个实例,则必须显式地将指针传递到该实例。例如,一些普通的C api有一个“上下文”指针,您可以在注册回调时传递它。请参见邻近的答案以获得相关示例。
#3
1
Either give self as an argument to the function call:
要么将self作为函数调用的参数:
void SetNotificationListeners(void *myObj){
[(MyClass*)myObj fireSpeechRecognition];
}
//in objC
SetNotificationListeners(self);
or have a global variable that holds reference
或者拥有一个包含引用的全局变量
//global variable
static MyClass *myObj;
//in obj c
myObj = self;
SetNotificationListeners(); //use myObj instead of self in function
The first is better in my opinion.
我认为第一个更好。
#4
1
In Objective-C methods there are two parameters that are implicitly passed into each method, which are self
and _cmd
. This is why you can access self
from within a method.
在Objective-C方法中,有两个参数隐式地传递给每个方法,即self和_cmd。这就是为什么您可以从一个方法中访问self。
You could just pass self
as an argument to your c function when calling from an Objective-C method, but with that trivial example I'm not sure why you wouldn't just use a method.
当调用Objective-C方法时,你可以将self作为参数传递给你的c函数,但是有了这个小例子,我不确定你为什么不只是使用一个方法。
You do not need to change the file extension to .mm
unless you are using Objective-C++
除非使用objective - c++,否则不需要将文件扩展名更改为.mm