Ошибка 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

Другие вопросы по тегам