使用
获取对象的类名作为字符串object_getClassName(myViewController)
返回类似这样的内容
_TtC5AppName22CalendarViewController
我正在寻找纯版本:“CalendarViewController”。如何获取类名的清理字符串?
我发现了一些有关此问题的尝试但不是真正的答案。这不可能吗?
答案 0 :(得分:454)
来自实例的字符串:
String(describing: YourType.self)
来自类型的字符串:
String(describing: self)
示例:
struct Foo {
// Instance Level
var typeName: String {
return String(describing: Foo.self)
}
// Instance Level - Alternative Way
var otherTypeName: String {
let thisType = type(of: self)
return String(describing: thisType)
}
// Type Level
static var typeName: String {
return String(describing: self)
}
}
Foo().typeName // = "Foo"
Foo().otherTypeName // = "Foo"
Foo.typeName // = "Foo"
使用class
,struct
和enum
进行了测试。
答案 1 :(得分:133)
更新为SWIFT 5
我们可以通过String
初始化程序和创建某个类的新对象 >使用实例变量来获取类型名称的漂亮描述
赞,例如print(String(describing: type(of: object)))
。其中object
可以是实例变量,例如数组,字典,Int
,NSDate
等
因为NSObject
是大多数Objective-C类层次结构的根类,所以您可以尝试为NSObject
创建扩展名以获取NSObject
的每个子类的类名。像这样:
extension NSObject {
var theClassName: String {
return NSStringFromClass(type(of: self))
}
}
或者您可以创建一个静态函数,其参数类型为Any
(所有类型隐式符合的协议),并将类名返回为String。像这样:
class Utility{
class func classNameAsString(_ obj: Any) -> String {
//prints more readable results for dictionaries, arrays, Int, etc
return String(describing: type(of: obj))
}
}
现在你可以这样做:
class ClassOne : UIViewController{ /* some code here */ }
class ClassTwo : ClassOne{ /* some code here */ }
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Get the class name as String
let dictionary: [String: CGFloat] = [:]
let array: [Int] = []
let int = 9
let numFloat: CGFloat = 3.0
let numDouble: Double = 1.0
let classOne = ClassOne()
let classTwo: ClassTwo? = ClassTwo()
let now = NSDate()
let lbl = UILabel()
print("diccionary: [String: CGFloat] = [:] -> \(Utility.classNameAsString(dictionary))")
print("array: [Int] = [] -> \(Utility.classNameAsString(array))")
print("int = 9 -> \(Utility.classNameAsString(int))")
print("numFloat: CGFloat = 3.0 -> \(Utility.classNameAsString(numFloat))")
print("numDouble: Double = 1.0 -> \(Utility.classNameAsString(numDouble))")
print("classOne = ClassOne() -> \((ClassOne).self)") //we use the Extension
if classTwo != nil {
print("classTwo: ClassTwo? = ClassTwo() -> \(Utility.classNameAsString(classTwo!))") //now we can use a Forced-Value Expression and unwrap the value
}
print("now = Date() -> \(Utility.classNameAsString(now))")
print("lbl = UILabel() -> \(String(describing: type(of: lbl)))") // we use the String initializer directly
}
}
此外,一旦我们可以将类名称作为String,我们就可以实现该类的新对象:
// Instanciate a class from a String
print("\nInstaciate a class from a String")
let aClassName = classOne.theClassName
let aClassType = NSClassFromString(aClassName) as! NSObject.Type
let instance = aClassType.init() // we create a new object
print(String(cString: class_getName(type(of: instance))))
print(instance.self is ClassOne)
也许这可以帮助那些人!
答案 2 :(得分:111)
以下是将typeName
作为变量(对于值类型或引用类型)的扩展。
protocol NameDescribable {
var typeName: String { get }
static var typeName: String { get }
}
extension NameDescribable {
var typeName: String {
return String(describing: type(of: self))
}
static var typeName: String {
return String(describing: self)
}
}
使用方法:
// Extend with class/struct/enum...
extension NSObject: NameDescribable {}
extension Array: NameDescribable {}
print(UITabBarController().typeName)
print(UINavigationController.typeName)
print([Int]().typeName)
答案 3 :(得分:30)
Swift 3.0
String(describing: MyViewController.self)
答案 4 :(得分:27)
我建议采用这种方式(非常Swifty ):
// Swift 3
func typeName(_ some: Any) -> String {
return (some is Any.Type) ? "\(some)" : "\(type(of: some))"
}
// Swift 2
func typeName(some: Any) -> String {
return (some is Any.Type) ? "\(some)" : "\(some.dynamicType)"
}
它既不使用内省也不使用手动demangling( no magic!)。
这是一个演示:
// Swift 3
import class Foundation.NSObject
func typeName(_ some: Any) -> String {
return (some is Any.Type) ? "\(some)" : "\(type(of: some))"
}
class GenericClass<T> {
var x: T? = nil
}
protocol Proto1 {
func f(x: Int) -> Int
}
@objc(ObjCClass1)
class Class1: NSObject, Proto1 {
func f(x: Int) -> Int {
return x
}
}
struct Struct1 {
var x: Int
}
enum Enum1 {
case X
}
print(typeName(GenericClass<Int>.self)) // GenericClass<Int>
print(typeName(GenericClass<Int>())) // GenericClass<Int>
print(typeName(Proto1.self)) // Proto1
print(typeName(Class1.self)) // Class1
print(typeName(Class1())) // Class1
print(typeName(Class1().f)) // (Int) -> Int
print(typeName(Struct1.self)) // Struct1
print(typeName(Struct1(x: 1))) // Struct1
print(typeName(Enum1.self)) // Enum1
print(typeName(Enum1.X)) // Enum1
答案 5 :(得分:18)
Swift 5.2:
String(describing: type(of: self))
答案 6 :(得分:17)
在 Swift 4.1 ,现在 Swift 4.2 :
import Foundation
class SomeClass {
class InnerClass {
let foo: Int
init(foo: Int) {
self.foo = foo
}
}
let foo: Int
init(foo: Int) {
self.foo = foo
}
}
class AnotherClass : NSObject {
let foo: Int
init(foo: Int) {
self.foo = foo
super.init()
}
}
struct SomeStruct {
let bar: Int
init(bar: Int) {
self.bar = bar
}
}
let c = SomeClass(foo: 42)
let s = SomeStruct(bar: 1337)
let i = SomeClass.InnerClass(foo: 2018)
let a = AnotherClass(foo: 1<<8)
如果您没有实例:
String(describing: SomeClass.self) // Result: SomeClass
String(describing: SomeStruct.self) // Result: SomeStruct
String(describing: SomeClass.InnerClass.self) // Result: InnerClass
String(describing: AnotherClass.self) // Result: AnotherClass
如果你有一个实例:
String(describing: type(of: c)) // Result: SomeClass
String(describing: type(of: s)) // Result: SomeStruct
String(describing: type(of: i)) // Result: InnerClass
String(describing: type(of: a)) // Result: AnotherClass
答案 7 :(得分:12)
您可以像这样使用名为_stdlib_getDemangledTypeName
的Swift标准库函数:
let name = _stdlib_getDemangledTypeName(myViewController)
答案 8 :(得分:11)
要在 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()))"
答案 9 :(得分:8)
您可以尝试这种方式:
a = [0, 9, 2, 2, 3, 2, 7, 5, 9, 5]
p a.chunk_while {|i, j| i <= j }.to_a
答案 10 :(得分:7)
也可以使用镜子:
let vc = UIViewController()
String(Mirror(reflecting: vc).subjectType)
注意:此方法也可用于Structs和Enums。有一个displayStyle可以指示结构的类型:
Mirror(reflecting: vc).displayStyle
返回是枚举,因此您可以:
Mirror(reflecting: vc).displayStyle == .Class
答案 11 :(得分:6)
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 ?? ""
}
}
答案 12 :(得分:4)
我一直在寻找这个答案。我使用GKStateMachine并喜欢观察状态变化,并想要一种简单的方法来查看类名。我不确定它只是iOS 10还是Swift 2.3,但在那种环境中,以下内容完全符合我的要求:
let state:GKState?
print("Class Name: \(String(state.classForCoder)")
// Output:
// Class Name: GKState
答案 13 :(得分:2)
在Class self或instance dynamicType上尝试echo off
REM This script is designed to demonstrate capture of volatile data from a Post Windows XP client
set /p path="Enter Drive Letter "
date /T > %path%:file.txt
time /T >> %path%:file.txt
getmac >> %path%:file.txt
hostname >> %path%:file.txt
ipconfig /all >> %path%:file.txt
arp -a >> %path%:file.txt
ipconfig /displaydns >> %path%:file.txt
netstat -an >> %path%:file.txt
。获取dynamicType之前解包可选项,否则dynamicType是可选包装器。
reflect().summary
摘要是一个描述泛型类型的类路径。要从摘要中获取简单的类名,请尝试使用此方法。
class SampleClass { class InnerClass{} }
let sampleClassName = reflect(SampleClass.self).summary;
let instance = SampleClass();
let instanceClassName = reflect(instance.dynamicType).summary;
let innerInstance = SampleClass.InnerClass();
let InnerInstanceClassName = reflect(innerInstance.dynamicType).summary.pathExtension;
let tupleArray = [(Int,[String:Int])]();
let tupleArrayTypeName = reflect(tupleArray.dynamicType).summary;
答案 14 :(得分:2)
你可以像这样在Swift 4中扩展NSObjectProtocol
:
import Foundation
extension NSObjectProtocol {
var className: String {
return String(describing: Self.self)
}
}
这将使所有类都可以使用计算变量className
。在print()
CalendarViewController
内使用此功能将在控制台中打印"CalendarViewController"
。
答案 15 :(得分:2)
以上解决方案对我不起作用。主要产生的问题在几条评论中提到:
MyAppName.ClassName
或
MyFrameWorkName.ClassName
此解决方案适用于XCode 9,Swift 3.0:
我将其命名为Map<String, String[]> map = //Map with data
try(BufferedWriter writer = new BufferedWriter(new FileWriter("<your_file>"))){
for(Map.Entry<String, String[]> entry : map.entrySet()){
writer.write(String.join(",", entry.getValue()));
writer.newLine();
}
}
,因此更容易访问,并且不会与未来的classNameCleaned
更改发生冲突:
className()
}
用法:
extension NSObject {
static var classNameCleaned : String {
let className = self.className()
if className.contains(".") {
let namesArray = className.components(separatedBy: ".")
return namesArray.last ?? className
} else {
return self.className()
}
}
答案 16 :(得分:1)
要从对象获取Swift类的名称,例如对于var对象:SomeClass(),使用
.bat
从类类型中获取Swift类的名称,例如SomeClass,使用:
String(describing: type(of: object))
输出:
“ SomeClass”
答案 17 :(得分:1)
此类用于var类的示例。不要包含捆绑软件的名称。
extension NSObject {
class var className: String {
return "\(self)"
}
}
答案 18 :(得分:1)
雨燕5
NSStringFromClass(CustomClass.self)
答案 19 :(得分:1)
我在Playground中使用Swift 3尝试了type(of:...)
。这是我的结果。
这是代码格式版本。
print(String(describing: type(of: UIButton.self)))
print(String(describing: type(of: UIButton())))
UIButton.Type
UIButton
答案 20 :(得分:1)
Swift 3.0(macOS 10.10及更高版本),您可以从className
获取它self.className.components(separatedBy: ".").last!
答案 21 :(得分:1)
要将类名称作为String,请将您的类声明为以下
@objc(YourClassName) class YourClassName{}
使用以下语法
获取类名NSStringFromClass(YourClassName)
答案 22 :(得分:0)
迅速5:
方法1:
print(“ Class:(String(describing:self)),Function:(#function),line:(#line)”)
输出:类:
方式2: print(“ Class:(String(describing:type(of:self))),Function:(#function),line:(#line)”) 输出:类:ViewController,功能:viewDidLoad(),行:16
答案 23 :(得分:0)
如果你不喜欢被破坏的名字,你可以指定自己的名字:
@objc(CalendarViewController) class CalendarViewController : UIViewController {
// ...
}
但是,从长远来看,学会解析受损的名称会更好。格式标准且有意义,不会发生变化。
答案 24 :(得分:0)
Swift 5.1
您可以通过Self.self
获取类,结构,枚举名称,并且可以在协议中使用它。
print("\(Self.self)")
答案 25 :(得分:0)
此解决方案适用于所有课程
Swift 5 解决方案:
extension NSObject {
var className: String {
return String(describing: type(of: self))
}
class var className: String {
return String(describing: self)
}
}
用法:
class TextFieldCell: UITableVIewCell {
}
class LoginViewController: UIViewController {
let cellClassName = TextFieldCell.className
}
答案 26 :(得分:0)
Swift 5.1:-
还可以使用泛型函数将对象的类名称作为字符串获取
struct GenericFunctions {
static func className<T>(_ name: T) -> String {
return "\(name)"
}
}
使用以下命令调用此函数:-
let name = GenericFunctions.className(ViewController.self)
快乐编码:)
答案 27 :(得分:0)
您可以通过以下方式获取类的名称:
class Person {}
String(describing: Person.self)
答案 28 :(得分:0)
有时其他解决方案会根据您尝试查看的对象提供无用的名称。在这种情况下,您可以使用以下内容将类名称作为字符串。
String(cString: object_getClassName(Any!))
⌘单击xcode中的函数以查看一些非常有用的相关方法。或点击此处https://developer.apple.com/reference/objectivec/objective_c_functions
答案 29 :(得分:0)
我在Swift 2.2中使用它
guard let currentController = UIApplication.topViewController() else { return }
currentController.classForCoder.description().componentsSeparatedByString(".").last!
答案 30 :(得分:-1)
在我的例子中,String(描述:self)返回了类似的内容:
&LT; My_project.ExampleViewController:0x10b2bb2b0&gt;
但我希望Android上有类似getSimpleName
的内容。
所以我创建了一个小扩展:
extension UIViewController {
func getSimpleClassName() -> String {
let describing = String(describing: self)
if let dotIndex = describing.index(of: "."), let commaIndex = describing.index(of: ":") {
let afterDotIndex = describing.index(after: dotIndex)
if(afterDotIndex < commaIndex) {
return String(describing[afterDotIndex ..< commaIndex])
}
}
return describing
}
}
现在又回来了:
ExampleViewController
扩展NSObject而不是UIViewController也应该有效。上述功能也是故障安全的:)