Swift Невозможно получить доступ к статическим переменным в классе, используя тип (of: Instance)

У меня есть несколько классов с одной и той же статической переменной. Я получаю currentInstance каждого класса во время выполнения (AnyObject?). Затем я пытаюсь получить доступ к статическим переменным путем получения класса из экземпляра с помощью метода type(of: instance). Но при попытке получить статическую переменную он выдает ошибку - значение типа AnyObject.Type не имеет члена. Вот псевдокод.

public extension Reader {
  open static var funcDictionary = [String: readerFuncs]() //ReaderFuncs is an enum of functions
}

public extension Library {
  open static var funcDictionary = [String: libraryFuncs]() 
}

public extension ReaderMenu {
  open static var funcDictionary = [String: readerMenuFuncs]() 
}


import Foundation
open class TestClass: NSObject {
  open func executeFunction(currentInstance: AnyObject) { // I get current instance at runtime. And I have checked that I get the correct value
  var count = type(of: currentInstance).functionDictionary.count // Error: Value of type 'AnyObject.Type' has no member funcDictionary 
}

Я хотел бы знать, как получить доступ к статическим переменным, когда у вас есть только экземпляр класса. Я тоже использовал.classforCoder(), но он не работает. Все файлы имеют одинаковое целевое членство тоже.

1 ответ

Вы должны использовать общие типы в вашем TestClassexecuteFunction метод, но нам нужна общая ссылка на все три ваших класса Reader, Library а также ReaderMenu, Для этого мы создадим протокол, которому должен соответствовать каждый класс.

protocol Funcable {

    associatedtype FuncsEnum

    static var funcDictionary: [String:FuncsEnum] { get set }
}

Теперь каждый класс наследует от Funcable все они должны иметь typealias, который определяет тип enum в funcDictionary,

class Reader: Funcable {

    typealias FuncsEnum = Reader.Funcs

    static var funcDictionary = [String:FuncsEnum]()

    enum Funcs {
        case A
        case B
    }
}

class Library: Funcable {

    typealias FuncsEnum = Library.Funcs

    static var funcDictionary = [String:FuncsEnum]()

    enum Funcs {
        case C
        case D
    }
}

class ReaderMenu: Funcable {

    typealias FuncsEnum = ReaderMenu.Funcs

    static var funcDictionary = [String:FuncsEnum]()

    enum Funcs {
        case E
        case F
    }
}

Вы можете определить свои перечисления вне классов, если хотите, но я переместил их внутрь, чтобы сделать их более пригодными для повторного использования. В любом случае, вернувшись в TestClass, мы можем использовать токен общего типа. T который является зеркалом класса данного currentInstance,

class TestClass: NSObject {

    func executeFunction<T: Funcable>(currentInstance: T) {

        print(T.funcDictionary.count)
    }
}

Для индивидуального доступа к перечислениям, например Reader.Funcs вместо readerFuncs

ОБНОВИТЬ

Мы можем просто создать экземпляр currentInstance самостоятельно, чтобы заставить это работать.

let testInstance = TestClass()

Reader.funcDictionary.updateValue(.A, forKey: "a")

testInstance.executeFunction(currentInstance: Reader()) // prints 1

Library.funcDictionary.updateValue(.C, forKey: "c")
Library.funcDictionary.updateValue(.D, forKey: "d")

testInstance.executeFunction(currentInstance: Library()) // prints 2
Другие вопросы по тегам