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 ответ
Вы должны использовать общие типы в вашем TestClass
executeFunction
метод, но нам нужна общая ссылка на все три ваших класса 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