Cocoa touch 在swift中获取用户可读的类名版本(在objc中,NSStringFromClass很好)

Cocoa touch 在swift中获取用户可读的类名版本(在objc中,NSStringFromClass很好),cocoa-touch,swift,Cocoa Touch,Swift,Swift中是否有一个NSStringFromClass的等价物,它提供了用户可读的类名版本?我尝试将其用于我创建的本机Swift类,但正如您所见,结果似乎是编译器对类名的内部表示: println(NSStringFromClass(MyClass.self)) 结果: _TtC5test7MyClass 我尝试将@objc属性添加到该类中,并将其作为NSObject的子类,但没有任何区别。我发现,如果我用一个同名的Objective-C类替换MyClass,并将其导入桥接头中,它会给我“

Swift中是否有一个NSStringFromClass的等价物,它提供了用户可读的类名版本?我尝试将其用于我创建的本机Swift类,但正如您所见,结果似乎是编译器对类名的内部表示:

println(NSStringFromClass(MyClass.self))
结果:

_TtC5test7MyClass
我尝试将@objc属性添加到该类中,并将其作为NSObject的子类,但没有任何区别。我发现,如果我用一个同名的Objective-C类替换MyClass,并将其导入桥接头中,它会给我“MyClass”,但这不是必需的

另一种选择是为此制定一个协议,我希望以这种方式使用的每个类都必须遵守该协议:

protocol Nameable {
    class var className: String { get }
}

但是,在语言中有一种内置的方法更容易做到这一点。

目前,没有可靠的方法可以做到这一点。参见苹果开发者对

斯威夫特目前没有太多的内省

有一些内省机制,用于 操场。我不知道这是否是为了API

一些敏捷的 方法和变量可以使用Objective-C运行时的 反省这可能是目前最好的解决方案

Swift确实有元类型的概念,有点类似于目标C中的类类型。您可以使用
TypeName.self
找到它,例如:

class Foo {
    @required  init() {
    }
}

var normalFoo : Foo = Foo()
var fooType : Foo.Type = Foo.self;
var fooFromMetatype : Foo = fooType();

也许,到发布时,元类型将包含更多的内省能力。我建议为此提交雷达功能请求。

如果您只想在swift中获得类的名称,可以解析NSStringFromClass()返回的字符串

这是以INSwift Github存储库的class.swift名称完成的:
基于xcode 6 beta 5的新格式

(项目名称)。(类别名称)


这并不是您想要的-它将添加一个不需要的前导“,您现在应该能够使用以下命令在swift中检索类名

let nameSpaceClassName = NSStringFromClass(RWTCountryPopoverViewController.self)
let className = nameSpaceClassName.componentsSeparatedByString(".").last! as String

这个短一点。无需
NSStringFromClass

MyObject.self.description().componentsSeparatedByString(".").last!

在Swift 2 beta 4中,您可以通过类型对象获取信息:

let className = "\(String.self)"   // gives: "Swift.String"
或者,如果您有一个实例:

let s = "Hello World"
let className = "\(s.dynamicType)" // gives: "Swift.String"
您将得到Module.Class结果,如:

Swift.String
ABC.MyGenericClass<Swift.Int>
Swift.String
ABC.MyGenericClass
有趣的是,返回的类型对象似乎不符合CustomStringConvertible协议。因此它没有“description”属性,尽管“”模式仍然做正确的事情

附言:在b4之前,同样可以通过reflect(obj.dynamicType).summary完成。

您现在只需执行以下操作:

String(MyClass)
-----更新-----

正如@ThomasW提到的,对于Swift 4,我们需要使用
String(description:type(of:self))

-----旧职位----

我更喜欢使用
String(self.dynamicType)


在我的项目中使用它

在Swift v3.0中,这对我很有用:

String.init(describing: self.self)

下面是带有代码的Swift 3+,Xcode 8+示例:

class MySuperbClass{
    let a = 4
    func getClassName() -> String? {
        return String(describing: type(of:self)).components(separatedBy: ".").first
    }
}


let className = String(describing: type(of:MySuperbClass.self)).components(separatedBy: ".").first
//className = "MySuperbClass" 
let classNameFromObject = MySuperbClass().getClassName()
//classNameFromObject = "MySuperbClass"

Swift 3

type(of:self)
printsModuleName.ClassName

String(description:type(of:self))
打印ClassName

swift3

NSStringFromClass(self).components(separatedBy: ".").last!
斯威夫特4

super.init(nibName:String(describing:MyClass.self), bundle: nil)

在最新版本的swift中,以下内容适用于我:

NSStringFromClass(type(of: device!.self))

请注意,这仅适用于类类型——如果您尝试使用协议,Swift将抱怨
错误:类型“MyProtocol”不符合协议“AnyObject”
classType。self
应仅编写为
classType
,这也适用于:
NSStringFromClass(self)。组件由字符串(“.”分隔。最后如下@NatashaTheRobot所述。现在只需使用
String(MyClass)
,这很酷,但在他们有一个显式的className()方法之前,我有点担心。Summary可能是现在的类名,但不能保证它会保持这种状态。这让我非常高兴!谢谢娜塔莎机器人。在《雨燕3》中,这已经不起作用了。Swift 3转换器将其更改为字符串(描述:MyClass),但这也不起作用。@您是否尝试过
String(描述:self)
或只是传递object
let object=MyClass()
String(描述:object)
对于Swift 4,这不再起作用,而是
String(描述:type(of:self))
确实如此。@ThomasW谢谢,我们已经更新了帖子以反映这些变化。
NSStringFromClass(self).components(separatedBy: ".").last!
super.init(nibName:String(describing:MyClass.self), bundle: nil)
NSStringFromClass(type(of: device!.self))