你能得到调用超级方法的子类的名称吗?

Can you get the name of the subclass calling a super method?

我通常将 create...:inContext: 方法添加到我的 NSManagedObject subclasses,该方法插入然后初始化对象。所以,例如:

class Example : NSManagedObject {
    class func createWithArgument(arg: Int, inContext context: NSManagedObjectContext) -> Example {
        let example = NSEntityDescription.insertNewObjectForEntityForName("Example", inManagedObjectContext: context) as! Example

       // ...
    }
}

这适用于特定的 classes,但如果 Example 是一个抽象模型,那么硬编码 "Example" 将不起作用。我想要做的是插入调用 createWithArgument:inContext: 方法的实体的类型,这样我就可以做这样的事情:

class SpecificExample : Example {
    class func createInContext(context: NSManagedObjectContext) -> SpecificExample {
        return super.createWithArgument(2, inContext: context)  // always 2 because reasons
    }
}

我最初的计划是只获取调用类型的名称并将其用作实体名称(前提是 class 和实体名称始终匹配)。

不幸的是,这似乎行不通;如您所见,即使您在 subclass:

上调用该方法,您始终会获得父类型
import UIKit

class Parent {
    class func getClassName(type: Any? = nil) -> String {
        return _stdlib_getDemangledTypeName(type ?? self).componentsSeparatedByString(".").first!
    }
}

class FirstChild : Parent {

}

class SecondChild : Parent {
    override class func getClassName(type: Any? = nil) -> String {
        return super.getClassName(self)
    }
}


Parent.getClassName() // Parent
FirstChild.getClassName() // Parent
SecondChild.getClassName() // SecondChild

现在,在我的具体示例中,还有其他方法可以达到相同的结果(例如,在 subclass 中创建对象,然后调用继承的 init 方法)。

然而,我现在很好奇在 Swift 中是否完全可以进行这种反省。有办法实现吗?

我不太明白你为什么不使用 NSStringFromClass():

class Parent {
    class func whoami() -> String {
        return NSStringFromClass(self)
    }
}
class FirstChild : Parent {
}
class SecondChild : Parent {
}

并且有一个纯 Swift 等价物,String()(或 Swift 1.2 及之前的 toString()):

class Parent {
    class func whoami() -> String {
        return String(self)
    }
}
class FirstChild : Parent {
}
class SecondChild : Parent {
}