我正在关注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
有什么问题?它是如何解决的?
答案 0 :(得分:1)
PerformSelector是一种早于GCD(Grand Central Dispatch)的Objective-C方法。它应该可以这样做,但选择器不是类型安全的并且使用起来很笨拙。
我不确定您当前的代码有什么问题。正如Martin在评论中指出的那样,您报告的错误是抱怨名为registerSources()
的方法,但是您显示了一个名为registerSource()
的方法的代码(没有最终的“e”。)如果您想要要使代码正常工作,您需要深入了解这种差异。
相反,为什么不使用这样的GCD代码:
dispatchQueue.main.async() {
registerSource(theContext)
}
这将实现相同的目标,但使用更现代的GCD