简体   繁体   中英

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?). Then I am trying to access static variables by getting a class from instance using type(of: instance) method. But when trying to get the static variable it throws me an error - Value of type 'AnyObject.Type' has no member . 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. 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 . 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 .

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 .

class TestClass: NSObject {

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

        print(T.funcDictionary.count)
    }
}

To access the enums individually eg Reader.Funcs instead of readerFuncs

UPDATE

We can just instantiate the currentInstance on our own to make it work.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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