【问题标题】:Swift Unable to access static variables in class using type(of: Instance)Swift无法使用类型(实例)访问类中的静态变量
【发布时间】:2016-09-09 01:23:45
【问题描述】:

我有多个具有相同静态变量的类。我在运行时获得每个类的 currentInstance(AnyObject?)。然后我试图通过使用 type(of: instance) 方法从实例中获取一个类来访问静态变量。但是当试图获取静态变量时,它会抛出一个错误 - Value of type 'AnyObject.Type' has no member 。这是伪代码。

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() 但它不起作用。所有文件也具有相同的目标成员资格。

【问题讨论】:

  • 您将不得不创建一个需要open static var funcDictionary 的协议,然后将您的TestClass 函数更改为open func executeFunction<T: ProtocolName>(currentInstance: T)。然后,您可以使用T.functionDictionary.count,而不是使用type(of:
  • 你的枚举是什么样的?
  • 我已经更新了我的答案并在操场上进行了测试,如果它适合你,请告诉我。

标签: swift xcode anyobject


【解决方案1】:

您应该在您的TestClassexecuteFunction 方法中使用泛型类型,但我们需要对您的所有三个类ReaderLibraryReaderMenu 的共同引用。为此,我们将创建一个每个类都必须遵守的协议。

protocol Funcable {

    associatedtype FuncsEnum

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

现在每个类都继承自Funcable,它们都需要有一个typealias来定义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

【讨论】:

  • 在我的驱动程序中,我得到了 currentInstance - var currenInstance? = someClass.getInstance()。 var test = TestClass(). test.executeFunction(currentInstance: currenInstance ) 给出错误消息“AnyObject 类型的参数?不确认为预期的 Funcable 类型”。这是因为 getInstance 返回的是 AnyObject 类型。但由于此 AnyObject 是 Library、Reader 类型(实现 Funcable),我不确定为什么这不起作用。
  • 这是因为currenInstance 的类型为AnyObject?,而executeFunction 需要符合协议Funcable 的类型。 someClass.getInstance() 来自哪里?
  • 它来自另一个类。类似于 :code class StateOption { getInstance(state: state) -> AnyObject? { case(state) { case .library: return Library() case .reader: return Reader() } } 在驱动程序中: var stateOption = StateOption() var currentInstance = stateOption.getInstance(state: state) var testInstance = TestClass( ) testInstance.executeFunction(currentInstance: currentInstance!) 另外Funcable也实现了类协议
  • 好吧,把getInstance(state: state) -&gt; AnyObject?改成getInstance(state: state) -&gt; Funcable?
  • 试过了。给我一个错误 --- 协议 'Funcable' 只能用作通用约束,因为它具有 Self 或关联的类型要求
猜你喜欢
  • 1970-01-01
  • 2019-03-12
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 2016-06-14
  • 2017-11-01
相关资源
最近更新 更多