全局函数和 AppDelegate 的 performSelector 错误 class

performSelector error with global function and AppDelegate class

我正在关注 this 苹果文档,我正在尝试将其部分内容翻译成 Swift 语言。我有这个全局函数,带有 performSelector:

func RunLoopSourceScheduleRoutine(info:UnsafeMutableRawPointer? ,rl:CFRunLoop? , mode:CFRunLoopMode?)  {

let obj :  RunLoopSource = Unmanaged<RunLoopSource>.fromOpaque(info!).takeUnretainedValue()
let del = UIApplication.shared
let theContext = RunLoopContext(withSource: obj, andLoop: rl!)

del.performSelector(onMainThread:#selector(AppDelegate.registerSource) , with: theContext, waitUntilDone: false)

}

和 AppDelegate class,在这个 class 中有:在项目创建的正常例程中自动添加 Xcode 的方法(didFinishLaunchingWithOptions、applicationWillResignActive 等) 我添加了 sourcesToPing参数和registerSource()方法:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    var sourcesToPing : [RunLoopContext] = Array()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    return true
}

    func registerSource(sourceInfo:RunLoopContext)  {
    sourcesToPing.append(sourceInfo)
}

}

但编译器在 RunLoopSourceScheduleRoutine() 函数中出现以下错误:

argument '#selector' refers to instance method 'registerSources(source Info:)' that is not exposed to Objective-C

有什么问题吗?它是如何解决的?

PerformSelector 是一种 Objective-C 方法,它早于 GCD(Grand Central Dispatch)。这样做应该是可行的,但是选择器不是类型安全的并且使用起来很笨拙。

我不确定您当前的代码有什么问题。正如 Martin 在他的评论中指出的那样,您报告的错误是抱怨一个名为 registerSources() 的方法,但您显示了一个名为 registerSource() 的方法的代码(没有最终的 "e"。)如果您想让该代码正常工作,您需要查明该差异的根源。

相反,为什么不使用这样的 GCD 代码:

dispatchQueue.main.async() {
  registerSource(theContext)
}

这将实现相同的目标,但使用更现代的 GCD