Ошибка executeSelector с глобальной функцией и классом AppDelegate
Я слежу за этим яблочным документом и пытаюсь перевести некоторые его части на язык Swift. У меня есть эта глобальная функция с executeSelector:
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 ответ
PerformSelector - это метод Objective-C, предшествующий GCD (Grand Central Dispatch). Должно быть возможно сделать это таким образом, но селекторы небезопасны и неудобны в использовании.
Я не уверен, что не так с вашим текущим кодом. Как указывает Мартин в своем комментарии, ошибка, о которой вы сообщаете, жалуется на метод, называемый registerSources()
но вы показываете код для метода с именем registerSource()
(без окончательного "е".) Если вы хотите, чтобы этот код работал, вам нужно докопаться до сути этой несоответствия.
Вместо этого, почему бы не использовать код GCD следующим образом:
dispatchQueue.main.async() {
registerSource(theContext)
}
Это достигнет той же цели, но с использованием более современного GCD