使用全局函数和AppDelegate类执行performSelector错误

时间:2016-12-24 11:32:00

标签: ios swift function global performselector

我正在关注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类,在这个类中有:自动在项目创建的常规例程中添加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

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

1 个答案:

答案 0 :(得分:1)

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

我不确定您当前的代码有什么问题。正如Martin在评论中指出的那样,您报告的错误是抱怨名为registerSources()的方法,但是您显示了一个名为registerSource()的方法的代码(没有最终的“e”。)如果您想要要使代码正常工作,您需要深入了解这种差异。

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

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

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