【问题标题】:Swift call class function from corresponding subclass in superclass functionSwift从超类函数中的相应子类调用类函数
【发布时间】:2014-07-12 09:20:52
【问题描述】:

我想在超类中实现init(coder aDecoder: NSCoder!),并通过在运行时调用超类中特定子类的类方法在所有子类中使用它。

MySuperClass

class func dummyDict() -> NSDictionary

init(coder aDecoder: NSCoder!) {

    for(key,value) in self.class.dummyDict(){
                      --------------------
                               ^
                               |
                               |
                 Get this from the corresponding subclass at runtime!

        NSLog("encoding \(value) for key \(key)")
    }

}

MySuperClass 的子类是否可以在运行时访问类函数dummyDict()

【问题讨论】:

  • 不确定我明白你的意思 - 您希望从任何子类调用该初始化程序,或者您希望该初始化程序调用在子类中被覆盖的基本方法(并调用正确的方法)?
  • 超类做一个get类并调用子类字典
  • 那么你想枚举基类的所有子类吗?如果是,我认为这是不可能的
  • 也许我知道你的意思...请看下面我的回答

标签: ios swift nscoding


【解决方案1】:

我想我明白你的意思了。您创建一个Base 类,实现一个初始化程序和一个类(静态)函数:

class Base {
    class func dummyDict() -> Dictionary<String, String> {
        return ["base1": "val1"]
    }

    init() {
        for (key, value) in self.dynamicType.dummyDict() {
            println("encoding \(value) for key \(key)")
        }
    }
}

接下来,您要创建子类,并让初始化程序调用 dummyDict 方法的重写版本。您只需覆盖该方法:

class Subclass1 : Base {
    override class func dummyDict() -> Dictionary<String, String> {
        return ["subclass1": "sub1"]
    }
}

现在,当您创建 Subclass1 的实例时,打印的内容是:

encoding sub1 for key subclass1

这是预期的输出。

注意初始化器中的for 循环使用self.dynamicType.dummyDict() 而不是Base.dummyDict()。后者总是调用Base类中定义的类方法,而前者在继承自Base的实际类的范围内调用它

【讨论】:

  • 我试图做同样的事情但不能让它工作,因为编译器会生成一个错误,告诉我我不能使用self.dynamicType.dummyDict(),因为我们不能使用@987654333 @ 在 init 方法内部(“在调用 self.init 之前在委托初始化程序中使用 self”)。有什么想法吗?
  • 嘿@AliSoftware,至少在swift 2.0中你可以在init函数中使用dynamicType self.dynamicType.dummyDict()。甚至在init() 被调用之前。否则尝试在init() 之后调用它,如果这对你来说是可能的。
【解决方案2】:

dynamicType 在 Swift 3 中已被弃用。我们必须使用 type(of:)

所以现在安东尼奥的例子是:

class Base {
    class func dummyDict() -> [String: String] {
        return ["base1": "val1"]
    }

    init() {
        for (key, value) in type(of: self).dummyDict() {
            print("encoding \(value) for key \(key)")
        }
    }
}

class Subclass1 : Base {
    override class func dummyDict() -> [String: String] {
        return ["subclass1": "sub1"]
    }
}

【讨论】:

    【解决方案3】:

    [删除]

    使用 dynamicType 正如安东尼奥在他的回答中建议的那样

    class Test : NSObject {
        class func dummy() -> String { 
            return "t"
        }
    
        init() {
            super.init()
            println("\(self.dynamicType.dummy())")
        }
    }
    
    class Test1 : Test {
        override class func dummy() -> String  {
            return "t1"
        }
    }
    
    class Test2 : Test {
        override class func dummy() -> String  {
            return "t2"
        }
    }
    

    【讨论】:

    • "class() 方法将返回 AnyClass!并且编译器在编译器时不知道类型..." 那么? object_getClass() 函数也返回 AnyClass!,这不是问题。
    • 它没有。但这并不意味着该函数不应该存在。
    • 我说的是object_getClass,不是objc_getClassTest 类的类型是Test.Type。如果你用let cls: Test.Type = object_getClass(self) as Test.Type; println("\(cls.dummy())") 代替上面的 println,它确实有效。
    • 无论如何,当您写“self.class 在 swift AFAICS 中不可用——因为这将是静态输入内容的主要问题”时,听起来您是在说 class 方法是'在 Swift 中不可用 因为 它的类型会成为一个问题。但是我展示了object_getClass 做同样的事情并且还返回AnyClass!,它在 Swift 中可用并且不是问题。这表明它的类型不是问题,他们可以在 Swift 中提供 class 方法;他们只是没有,出于其他原因。
    猜你喜欢
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    相关资源
    最近更新 更多