使用获取对象的类名作为字符串
object_getClassName(myViewController)
Run Code Online (Sandbox Code Playgroud)
返回这样的东西
_TtC5AppName22CalendarViewController
Run Code Online (Sandbox Code Playgroud)
我正在寻找纯版本:"CalendarViewController".如何获得清理的类名字符串?
我发现了一些有关此问题的尝试但不是真正的答案.这不可能吗?
Rud*_*vič 493
来自实例的字符串:
String(describing: YourType.self)
Run Code Online (Sandbox Code Playgroud)
类型中的字符串:
String(describing: self)
Run Code Online (Sandbox Code Playgroud)
例:
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"
Run Code Online (Sandbox Code Playgroud)
经过测试class
,struct
和enum
.
mau*_*nde 161
更新SWIFT 4.2
我们可以通过初始化程序使用实例变量获得类型名称的漂亮描述,String
并创建某个类的新对象
比如,例如print(String(describing: type(of: object)))
.哪里object
可以是一个实例变量,如数组,字典,a Int
,a NSDate
等.
因为NSObject
是大多数Objective-C类层次结构的根类,所以你可以尝试扩展NSObject
以获取每个子类的类名NSObject
.像这样:
extension NSObject {
var theClassName: String {
return NSStringFromClass(type(of: self))
}
}
Run Code Online (Sandbox Code Playgroud)
或者你可以创建一个静态函数,其参数是类型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))
}
}
Run Code Online (Sandbox Code Playgroud)
现在你可以这样做:
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("dictionary: [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
}
}
Run Code Online (Sandbox Code Playgroud)
此外,一旦我们可以将类名称作为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)
Run Code Online (Sandbox Code Playgroud)
也许这有助于那里的人!
nah*_*g89 117
这是获取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)
}
}
Run Code Online (Sandbox Code Playgroud)
如何使用:
// Extend with class/struct/enum...
extension NSObject: NameDescribable {}
extension Array: NameDescribable {}
print(UITabBarController().typeName)
print(UINavigationController.typeName)
print([Int]().typeName)
Run Code Online (Sandbox Code Playgroud)
sli*_*lim 31
Swift 3.0
String(describing: MyViewController.self)
wer*_*ver 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)"
}
Run Code Online (Sandbox Code Playgroud)
它既不使用内省也不使用手动解码(没有魔法!).
这是一个演示:
// 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
Run Code Online (Sandbox Code Playgroud)
set*_*fri 22
如果你有类型Foo
,下面的代码将"Foo"
在Swift 3和Swift 4中给你:
let className = String(describing: Foo.self) // Gives you "Foo"
Run Code Online (Sandbox Code Playgroud)
这里的大多数答案的问题是,"Foo.Type"
当你没有任何类型的实例时,它们会将你作为结果字符串,当你真正想要的只是"Foo"
.以下为您"Foo.Type"
提供了一些其他答案中提到的内容.
let className = String(describing: type(of: Foo.self)) // Gives you "Foo.Type"
Run Code Online (Sandbox Code Playgroud)
type(of:)
如果你只是想要,这部分是不必要的"Foo"
.
Vic*_*rov 19
斯威夫特 5.1
你可以得到类、结构、枚举、协议和 NSObject 名称Self.self
。
print("\(Self.self)")
Run Code Online (Sandbox Code Playgroud)
McN*_*ght 18
在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)
Run Code Online (Sandbox Code Playgroud)
如果您没有实例:
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
Run Code Online (Sandbox Code Playgroud)
如果你有一个实例:
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
Run Code Online (Sandbox Code Playgroud)
Ash*_*iya 15
斯威夫特5:
方式一:
print("Class: \(String(describing: self)), Function: \(#function), line: \(#line)")
Run Code Online (Sandbox Code Playgroud)
输出:
Class: <Test.ViewController: 0x7ffaabc0a3d0>, Function: viewDidLoad(), line: 15
Run Code Online (Sandbox Code Playgroud)
方式二:
print("Class: \(String(describing: type(of: self))), Function: \(#function), line: \(#line)")
Run Code Online (Sandbox Code Playgroud)
输出:
Class: ViewController, Function: viewDidLoad(), line: 16
Run Code Online (Sandbox Code Playgroud)
Jer*_*ner 12
您可以使用这样调用的Swift标准库函数_stdlib_getDemangledTypeName
:
let name = _stdlib_getDemangledTypeName(myViewController)
Run Code Online (Sandbox Code Playgroud)
Mis*_*nko 11
要在Swift 4中将类型名称作为字符串获取(我还没有检查过早期版本),只需使用字符串插值:
"\(type(of: myViewController))"
Run Code Online (Sandbox Code Playgroud)
您可以.self
在类型本身上使用,并在type(of:_)
实例上使用该函数:
// Both constants will have "UIViewController" as their value
let stringFromType = "\(UIViewController.self)"
let stringFromInstance = "\(type(of: UIViewController()))"
Run Code Online (Sandbox Code Playgroud)
小智 8
您可以NSObjectProtocol
像这样在 Swift 4 中进行扩展:
import Foundation
extension NSObjectProtocol {
var className: String {
return String(describing: Self.self)
}
}
Run Code Online (Sandbox Code Playgroud)
这将使className
所有类都可以使用计算变量。在print()
in 中使用它CalendarViewController
会"CalendarViewController"
在控制台中打印。
也可以使用镜子:
let vc = UIViewController()
String(Mirror(reflecting: vc).subjectType)
Run Code Online (Sandbox Code Playgroud)
注意:此方法也可用于结构和枚举.有一个displayStyle可以指示结构的类型:
Mirror(reflecting: vc).displayStyle
Run Code Online (Sandbox Code Playgroud)
返回是枚举,因此您可以:
Mirror(reflecting: vc).displayStyle == .Class
Run Code Online (Sandbox Code Playgroud)
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 ?? ""
}
}
Run Code Online (Sandbox Code Playgroud)
要从对象获取Swift类的名称,例如var对象:SomeClass(),请使用
String(describing: type(of: object))
Run Code Online (Sandbox Code Playgroud)
要从类类型(例如SomeClass)中获取Swift类的名称,请使用:
String(describing: SomeClass.self)
Run Code Online (Sandbox Code Playgroud)
输出:
“ SomeClass”
要将类名作为字符串声明您的类,如下所示
@objc(YourClassName) class YourClassName{}
Run Code Online (Sandbox Code Playgroud)
并使用以下语法获取类名
NSStringFromClass(YourClassName)
Run Code Online (Sandbox Code Playgroud)
我一直在断断续续地寻找这个答案。我使用 GKStateMachine 并且喜欢观察状态变化并且想要一种简单的方法来查看类名。我不确定它是否只是 iOS 10 或 Swift 2.3,但在该环境中,以下内容正是我想要的:
let state:GKState?
print("Class Name: \(String(state.classForCoder)")
// Output:
// Class Name: GKState
Run Code Online (Sandbox Code Playgroud)
小智 5
您可以通过执行以下操作来获取类的名称:
class Person {}
String(describing: Person.self)
Run Code Online (Sandbox Code Playgroud)
如果您不喜欢损坏的名称,您可以指定自己的名称:
@objc(CalendarViewController) class CalendarViewController : UIViewController {
// ...
}
Run Code Online (Sandbox Code Playgroud)
然而,从长远来看,学习解析损坏的名称会更好。格式是标准的、有意义的,不会改变。
归档时间: |
|
查看次数: |
179475 次 |
最近记录: |