在Swift中将对象的类名作为字符串获取

432

使用以下方法将对象的类名获取为 String

object_getClassName(myViewController)

返回类似于这样的内容:

_TtC5AppName22CalendarViewController

我正在寻找纯净的版本:"CalendarViewController"。那么如何获取一个清理过的类名字符串呢?

我找到了一些关于这个问题的尝试,但没有实际的答案。难道完全不可能吗?


或者说,一个有效的解析器函数应该是什么样子的? - Bernd
如果您想检查一个对象是否属于某个类,请参见此答案 - meaning-matters
32个回答

17

你可以尝试这种方法:

self.classForCoder.description()

这个非常好用,因为它包含了完整的“命名空间”(适当的目标成员前缀)。 - BonanzaDriver
顺便说一句,我也发现在MyViewController实例中使用"String(self)"也可以...它提供了相同的信息...Xcode 7.1。 - BonanzaDriver

15
在Swift 4中(我没有检查早期版本),要将类型名称作为字符串获取,只需使用字符串插值:
"\(type(of: myViewController))"

您可以在类型本身上使用.self,并在实例上使用type(of:_) 函数:

// Both constants will have "UIViewController" as their value
let stringFromType = "\(UIViewController.self)"
let stringFromInstance = "\(type(of: UIViewController()))"

15

Swift 5:

方法一:

print("Class: \(String(describing: self)), Function: \(#function), line: \(#line)")

输出:

Class: <Test.ViewController: 0x7ffaabc0a3d0>, Function: viewDidLoad(), line: 15

第二种方法:

print("Class: \(String(describing: type(of: self))), Function: \(#function), line: \(#line)")

输出:

Class: ViewController, Function: viewDidLoad(), line: 16

13
你可以使用Swift标准库函数_stdlib_getDemangledTypeName,方法如下:
let name = _stdlib_getDemangledTypeName(myViewController)

@NeilJaff 你说的“只是一个可选字符串”是什么意思?它返回一个字符串,而且不是可选的。 - Jernej Strasner
3
这种方法不会返回私有API类的名称,仅会返回第一个公共基类的名称。FYI。 - Tylerc230
我收到了这条消息:使用未解决的标识符'_stdlib_getDemangledTypeName'。 - Blazej SLEBODA

10

人们也可以使用镜子:

let vc = UIViewController()

String(Mirror(reflecting: vc).subjectType)

注意:此方法也适用于结构体和枚举。displayStyle可以显示结构的类型。

Mirror(reflecting: vc).displayStyle

返回值是一个枚举类型,因此您可以:

Mirror(reflecting: vc).displayStyle == .Class

谢谢。这对我有用。唯一的问题是(至少在iOS 9上),subjectType以“.Type”结尾,所以我必须从字符串中删除该部分。 - Nikolay Suvandzhiev

9
你可以像这样在Swift 4中扩展NSObjectProtocol:
import Foundation

extension NSObjectProtocol {

    var className: String {
        return String(describing: Self.self)
    }
}

这将使得计算变量className对所有类都可用。在CalendarViewController中使用print()将会在控制台输出"CalendarViewController"

9

Swift 3.0: 你可以像这样创建一个扩展。它会返回类名而不包含项目名称。

extension NSObject {
    var className: String {
        return NSStringFromClass(self as! AnyClass).components(separatedBy: ".").last ?? ""
    }

    public class var className: String {
        return NSStringFromClass(self).components(separatedBy: ".").last ?? ""
    }
}

当我尝试使用它时,出现错误:无法将类型为“ProjectName.MyViewController”(0x1020409e8)的值转换为“Swift.AnyObject.Type”(0x7fb96fc0dec0)。 - tylerSF

6

我一直在找这个答案,我使用GKStateMachine并且希望观察状态变化,并想要一个简单的方法来查看类名。 我不确定它是iOS 10还是Swift 2.3,但在那个环境中,以下内容正好符合我的要求:

let state:GKState?
print("Class Name: \(String(state.classForCoder)")

// Output:    
// Class Name: GKState

6
您可以通过以下方式获取类名:
class Person {}
String(describing: Person.self)

5
要将类名作为字符串获取,请按以下方式声明您的类:
@objc(YourClassName) class YourClassName{}

使用以下语法获取类名:
NSStringFromClass(YourClassName)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接