Swift无法使用类型(实例)访问类中的静态变量

Posted

技术标签:

【中文标题】Swift无法使用类型(实例)访问类中的静态变量【英文标题】:Swift Unable to access static variables in class using type(of: Instance) 【发布时间】: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: 你的枚举是什么样的? 我已经更新了我的答案并在操场上进行了测试,如果它适合你,请告诉我。 【参考方案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 或关联的类型要求

以上是关于Swift无法使用类型(实例)访问类中的静态变量的主要内容,如果未能解决你的问题,请参考以下文章

无法访问扩展 Objective-C 类的 Swift 类中的私有变量

Java 类中的哪些变量构造函数可以访问?

关于类中静态成员函数和静态成员变量的知识点

浅谈C++类中的static

子类能不能继承父类的成员变量

类的成员