Попытка вызвать селектор статической функции в быстром

голоса
1

Я пытаюсь добиться следующего, но я бегу в вопросы :-)

  • создать протокол, который UIViewController и UIView подкласс может принять, которые содержат один статический метод, вызываемый по этому классу (назовем его configuration
  • Затем я хочу использовать ObjectiveC выполнения, чтобы найти классы, которые принимают этот протокол
  • На каждом из этого класса я хочу , чтобы вызвать configurationметод
  • Метод конфигурации для возврата словаря (ключ: строка описания, значение: селектор будет называться по классу)

До сих пор я был в состоянии создать протокол, найти класс, реализующий протокол, но я бегаю в компиляции вопросы.

Вот протокол

@objc public protocol MazeProtocol: NSObjectProtocol{
   @objc static func configurations() -> NSDictionary
}

Вот расширение принять протокол об одном из моего класса:

extension MapCoordinatorViewController: MazeProtocol {

static func configurations() -> NSDictionary {
    let returnValue = NSMutableDictionary()
    returnValue.setObject(#selector(test), forKey: test as NSString)
    return returnValue
}

@objc static func test() {

    print(test)
}}

а вот код, я использую, чтобы попытаться вызвать селектор, возвращенное методом конфигурации:

let selectorKey = controllerClass.configurations().allKeys[indexPath.row]
let selector = controllerClass.configurations().object(forKey: selectorKey)
controllerClass.performSelector(selector)        <================ error here

ControllerClass объявлен как let controllerClass: MazeProtocol.Type

Я получаю следующее предупреждение компиляции: Instance member 'performSelector' cannot be used on type 'MazeProtocol'

Что мне не хватает?

Задан 27/11/2018 в 15:00
источник пользователем
На других языках...                            


1 ответов

голоса
4

Вы можете технически заставить это работать. Пожалуйста, не. Это ужасно Swift. Для того, чтобы получить эту работу, вы должны подрывать все Свифт пытается сделать. Но да, с предупреждениями, вы можете технически получить это скомпилировать и работать. Пожалуйста, пожалуйста, не.

Во- первых, вы должны сделать selectorбыть Selector. Вы используете NSDictionary, который страшен в Swift, и таким образом вы получаете Any?обратно. Но, да, вы можете as!бросить его в то , что вы хотите:

let selector = controllerClass.configurations().object(forKey: selectorKey) as! Selector

И затем, бросая вызов всем богам типа, можно просто объявить , что классы на самом деле NSObjectProtocol, потому что почему бы и нет?

(controllerClass as! NSObjectProtocol).perform(selector)

Это выбросит предупреждение «Cast от„MapCoordinatorViewController.Type“к неродственной типа„NSObjectProtocol“всегда терпит неудачу», но это будет на самом деле добиться успеха.

В конце концов, что «не делать этого», как вы должны это сделать? С закрытием.

public protocol MazeProtocol {
    static var configurations: [String: () -> Void] { get }
}

class MapCoordinatorViewController: UIViewController {}

extension MapCoordinatorViewController: MazeProtocol {

    static let configurations: [String: () -> Void] = [
        "test": test
    ]
    static func test() {
        print("test")
    }
}


let controllerClass = MapCoordinatorViewController.self
let method = controllerClass.configurations["test"]!
method()
Ответил 27/11/2018 в 18:33
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more