【问题标题】:How to call Objective-C "self" from C method [duplicate]如何从C方法调用Objective-C“self”[重复]
【发布时间】:2013-11-24 09:29:49
【问题描述】:

我的iOS 项目中有Objective-C 类,它在同一类中实现Objective-CC 代码。我将扩展名更改为.mm,这部分进展顺利。现在我想设置一个C 方法,它将在同一个类中调用Objective-C 方法。我遇到的问题是当我尝试从 C 方法调用 self 时。 这是代码:

void SetNotificationListeners(){
    [self fireSpeechRecognition];
}

错误是:

Use of undeclared identifier 'self'

我该如何管理?

【问题讨论】:

  • 那是 iOS,不是 IOS。无论如何,你为什么期望self 可以从一个 属于该类的函数中访问?那是没有意义的。您需要将实例(对象)本身作为参数传递。
  • 为什么你在使用Objective-C和C(你没有提到C++)的时候把扩展名改为.mm

标签: ios objective-c c


【解决方案1】:

您必须将实例指针传递给 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));
}

(只有在使用 ARC 编译时才需要“brigde”的东西。)

【讨论】:

  • 读完这篇文章我会问,你在 C 中的什么地方叫 Objective C ?在这里你说“从Objective-C调用C函数”......不明白......这让我感到困惑! rs
【解决方案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

我认为第一个更好。

【讨论】:

  • 第二个是疯狂:)
  • 正如我所说,我更喜欢第一个选项。有趣的是,当在现在发现的这个问题的重复中以 10 票赞成的标记答案只是提到相同的“疯狂”时,我是如何被否决的......
【解决方案3】:

您不必更改文件扩展名。 Objective-C 是 C 的超集,这意味着您可以在自己的 Objective-C 文件中随意使用纯 C。

当您编写一个 Objective-C 方法的实现时,该方法总是在某个特定实例的上下文中执行,这就是self 部分。您在 Objective-C 方法中自动获得self,但在幕后它只是作为参数传递给方法,请参阅obc_msgsend

你的普通 C 函数不是类的一部分(普通 C 函数从来不是),因此当你调用它时没有与之关联的实例,也没有隐含的 self。如果您希望函数调用某个实例,则必须显式传递指向该实例的指针。例如,一些普通的 C API 有一个“上下文”指针,您可以在注册回调时传递。有关此示例,请参阅相邻答案。

【讨论】:

    【解决方案4】:

    在 Objective-C 方法中,有两个参数被隐式传递给每个方法,它们是 self_cmd。这就是您可以从方法中访问self 的原因。

    在从 Objective-C 方法调用时,您可以将 self 作为参数传递给您的 c 函数,但是对于这个简单的示例,我不确定您为什么不只使用方法。

    除非您使用的是 Objective-C++,否则您无需将文件扩展名更改为 .mm

    【讨论】:

      猜你喜欢
      • 2023-03-29
      • 2014-11-13
      • 1970-01-01
      • 1970-01-01
      • 2011-05-26
      • 2012-04-29
      • 2012-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多