简体   繁体   English

Swift无法使用type(of:Instance)访问类中的静态变量

[英]Swift Unable to access static variables in class using type(of: Instance)

I have multiple classes with the same static variable. 我有多个具有相同静态变量的类。 I get the currentInstance of each class at runtime(AnyObject?). 我在运行时获取每个类的currentInstance(AnyObject?)。 Then I am trying to access static variables by getting a class from instance using type(of: instance) method. 然后,我尝试通过使用type(of:instance)方法从实例获取类来访问静态变量。 But when trying to get the static variable it throws me an error - Value of type 'AnyObject.Type' has no member . 但是,当尝试获取静态变量时,会引发错误-类型为'AnyObject.Type'的值没有成员。 Here is pseudo code. 这是伪代码。

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 
}

I would like to know how to access static variables when you only have the instance of the class available. 我只想知道在只有该类实例可用时如何访问静态变量。 I have used .classforCoder() too but it doesn't work. 我也使用过.classforCoder(),但是它不起作用。 All the files have the same target membership too. 所有文件也具有相同的目标成员资格。

You should use generic types in your TestClass executeFunction method, but we need a common reference to all three of your classes Reader , Library and ReaderMenu . 您应该在TestClass executeFunction方法中使用泛型类型,但是我们需要对所有三个类ReaderLibraryReaderMenu的通用引用。 To do that, we will create a protocol that each class has to conform to. 为此,我们将创建每个类都必须遵循的协议。

protocol Funcable {

    associatedtype FuncsEnum

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

Now each class inherits from Funcable , they are all required to have a typealias that defines the type of enum in the funcDictionary . 现在,每个类都从Funcable继承,它们都必须具有定义funcDictionary中的枚举类型的类型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
    }
}

You can define your enums outside of the classes if you like, but I've moved them inside to make it more reusable. 您可以根据需要在类之外定义枚举,但为了将其重新使用,我将它们移入了内部。 Anyway back at the TestClass, we can use Generic Type Token T which is a mirror of the class of the given currentInstance . 无论如何回到TestClass,我们都可以使用通用类型令牌T ,它是给定currentInstance类的镜像。

class TestClass: NSObject {

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

        print(T.funcDictionary.count)
    }
}

To access the enums individually eg Reader.Funcs instead of readerFuncs 单独访问枚举,例如Reader.Funcs而不是readerFuncs

UPDATE 更新

We can just instantiate the currentInstance on our own to make it work. 我们可以自己实例化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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM