【问题标题】:Check existence of global function in Swift检查 Swift 中是否存在全局函数
【发布时间】:2016-11-16 03:30:03
【问题描述】:

是否可以检测是否定义了某些 全局函数(不是类方法)(在 iOS 中)?像respondsToSelector 一类的东西...

【问题讨论】:

  • 您是专门寻找 Swift 函数还是从 Apple 框架导入的 C 函数?
  • @NikolaiRuhe 我想知道,你能检测到它们中的任何一个吗?
  • @NikolaiRuhe 一切都有帮助。
  • 如果它是全局函数,那么你为什么要关心检查它的存在。只是好奇
  • @NikolaiRuhe 在 Swift 中,我们应该为此使用 #available。

标签: ios swift introspection


【解决方案1】:

不,这在 Swift 中是不可能的。

即使respondsToSelector 使用 Obj-C 运行时,也只能用于 Obj-C 中可用的功能。

【讨论】:

  • 如果函数不存在,你将如何通过编译器?
  • @Feldur 这就是为什么我们有#available。
  • @Feldur 您总是可以声明一个函数(如extern,但这是默认值),然后将其留给动态链接器来解析符号。这就是链接到系统框架时一直发生的事情。
  • 这个问题与在 Swift 中执行此操作无关吗? extern 似乎不是一个 swift 关键字
【解决方案2】:

Swift 目前不支持查找全局函数。

对于 C 函数(Apple 框架中的大多数全局函数都是 C 函数),至少有两种方法:

  • 使用弱链接符号
  • 动态链接器 API:dlopen

两者都动态检查(在运行时)是否可以找到符号。

这是一个检查UIGraphicsBeginImageContextWithOptions(iOS 4 引入)是否可用的示例:

void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale) __attribute__((weak));

static inline BOOL hasUIGraphicsBeginImageContextWithOptions() {
    return UIGraphicsBeginImageContextWithOptions != NULL;
}

这是同样的检查,使用dlsym:

#import <dlfcn.h>

static inline BOOL hasUIGraphicsBeginImageContextWithOptions() {
    return dlsym(RTLD_SELF, "UIGraphicsBeginImageContextWithOptions") != NULL;
}

使用dlsym 的优点是您不需要声明,而且它很容易移植到 Swift。

【讨论】:

  • 现在我记得我自己之前确实使用过弱链接。不过,我不确定这是否适用于 Swift 全局变量。
  • @Sulthan 不会,因为 Objective-C 看不到 Swift 全局变量。但也许这不是 OP 所要求的。
  • @Sulthan Swift 的名字修改阻止了简单的符号查找。
猜你喜欢
  • 1970-01-01
  • 2018-07-07
  • 1970-01-01
  • 2012-05-03
  • 2022-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-08
相关资源
最近更新 更多