【问题标题】:Objective C - Call Method defined from a MacroObjective C - 从宏定义的调用方法
【发布时间】:2020-06-04 15:23:39
【问题描述】:

我正在尝试从 Objective-C 调用一个方法,该方法已使用包含 Swift 函数的宏定义。当我尝试调用我的方法时,我在 Xcode 中收到编译错误No visible @interface for 'NearbyMessages' declares the selector '__rct_export__disconnect'

我的 Swift 函数如下所示:

// SomeInterface.swift

@objc
func disconnect() -> Void {
    // (disconnect logic here)
}

Objective-C 代码如下所示:

// SomeInterface.m
@interface RCT_EXTERN_REMAP_MODULE(SomeInterfaceNameJS, SomeInterfaceNamePrivate, NSObject)

RCT_EXTERN_METHOD(disconnect);
-(void) invalidate {
    [self __rct_export__disconnect];   // No visible @interface for 'NearbyMessages' declares the selector '__rct_export__disconnect'
    NSLog(@"GNM_BLE: invalidate!");
}

@end

RCT_EXTERN_METHOD(来自 React 的 RCTBridgeModule.h)定义为:

#define RCT_EXTERN_METHOD(method) \
  _RCT_EXTERN_REMAP_METHOD(, method, NO)

#define _RCT_EXTERN_REMAP_METHOD(js_name, method, is_blocking_synchronous_method) \
  + (const RCTMethodInfo *)RCT_CONCAT(__rct_export__, RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) { \
    static RCTMethodInfo config = {#js_name, #method, is_blocking_synchronous_method}; \
    return &config; \
  }

通过阅读本文,编译后的方法应该被称为__rct_export__disconnect,对吧?

那么为什么不能使用[self __rct_export__disconnect] - 我还能怎么调用这个方法呢?

【问题讨论】:

    标签: objective-c swift react-native native-module react-native-native-module


    【解决方案1】:

    TL;DR:要回答这个问题,请致电[self.class __rct_export__disconnect];。但更好的方法是直接调用disconnect() 函数(如果__rct_export__ 前缀在下一版本的 React Native 中发生变化,这是唯一一种面向未来的方法)。


    Objective-C 允许有两种主要类型的方法。

    第一种类型是实例方法,它对Objective-C 类的一个实例进行操作。在此方法的主体中,self 是指向堆上对象实例的指针,因此得名。通过self 指针,您可以访问其他实例方法、实例变量等。它在开头用减号 (-) 声明/定义。

    第二种类型是类方法,它作用于类对象(一个特定的Obj-C结构)。当您在其他语言中使用静态函数时,它最常用(当然还有一些与继承相关的警告和怪癖)。在这个方法的主体中,self 是一个指向类对象的指针。通过它您可以调用其他类方法,但您无权访问对象的任何具体实例。

    区别解释得很好here


    在你的例子中,这个宏定义了一个类方法:

    #define _RCT_EXTERN_REMAP_METHOD(js_name, method, is_blocking_synchronous_method) \
      + (const RCTMethodInfo *)RCT_CONCAT(__rct_export__, RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) { \
        static RCTMethodInfo config = {#js_name, #method, is_blocking_synchronous_method}; \
        return &config; \
      }
    

    而且这个方法是实例方法:

    - (void)invalidate {
        [self __rct_export__disconnect];   // No visible @interface for 'NearbyMessages' declares the selector '__rct_export__disconnect'
        NSLog(@"GNM_BLE: invalidate!");
    }
    

    当您从实例方法调用[self __rct_export__disconnect];] 时,self 指向您的类的实例__rct_export__disconnect 被定义为类方法(参见宏),因此它没有定义在对象的实例上。

    【讨论】:

    • 这是一个非常好的答案,将其标记为已接受 - 但是如果有人偶然发现同样的问题,我发现也可以在 Swift 中创建 invalidate func 并将其公开给 Objective -C (@objc)。
    • @mrousavy,您是否有将 swift 函数公开给 Objective-C 的示例?因为这实际上就是我们在这个问题中试图做的事情,几行代码就可以创造奇迹!谢谢。
    猜你喜欢
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-12
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    相关资源
    最近更新 更多