所以我试图在Swift中将实际变量名称作为字符串,但是还没有找到方法这样做......或者我可能正在以一个不好的角度看待这个问题和解决方案。
所以这基本上就是我想做的事情:
var appId: String? = nil
//This is true, since appId is actually the name of the var appId
if( appId.getVarName = "appId"){
appId = "CommandoFurball"
}
不幸的是,我无法在苹果文档中找到任何与此相近的内容,但是:
varobj.self or reflect(var).summary
然而,这给出了变量本身内部或变量类型的信息,在这种情况下是String,我想要变量的实际名称。
答案 0 :(得分:48)
使用#keyPath()
https://github.com/apple/swift-evolution/blob/master/proposals/0062-objc-keypaths.md
示例用法如下:
NSPredicate(format: "%K == %@", #keyPath(Person.firstName), "Wendy")
在 Swift 4 中我们有更好的表现:\KeyPath
符号
https://github.com/apple/swift-evolution/blob/master/proposals/0161-key-paths.md
NSPredicate(format: "%K == %@", \Person.mother.firstName, "Wendy")
// or
let keyPath = \Person.mother.firstName
NSPredicate(format: "%K == %@", keyPath, "Andrew")
速记是一个受欢迎的补充,能够从变量引用键路径是非常强大的
答案 1 :(得分:25)
根据this answer的更新,通过#keyPath
NSPredicate(format: "%K == %@", #keyPath(Person.firstName), "Andrew")
答案 2 :(得分:3)
这是我的解决方法
class Test {
var name: String = "Ido"
var lastName: String = "Cohen"
}
let t = Test()
let mirror = Mirror(reflecting: t)
for child in mirror.children {
print(child.label ?? "")
}
将是
name
lastName
答案 3 :(得分:1)
最佳解决方案是Here
来自指定链接
import Foundation
extension NSObject {
//
// Retrieves an array of property names found on the current object
// using Objective-C runtime functions for introspection:
// https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html
//
func propertyNames() -> Array<String> {
var results: Array<String> = [];
// retrieve the properties via the class_copyPropertyList function
var count: UInt32 = 0;
var myClass: AnyClass = self.classForCoder;
var properties = class_copyPropertyList(myClass, &count);
// iterate each objc_property_t struct
for var i: UInt32 = 0; i < count; i++ {
var property = properties[Int(i)];
// retrieve the property name by calling property_getName function
var cname = property_getName(property);
// covert the c string into a Swift string
var name = String.fromCString(cname);
results.append(name!);
}
// release objc_property_t structs
free(properties);
return results;
}
}
答案 4 :(得分:1)
我已经提出了一个快捷的解决方案,但不幸的是它不适用于Int的Float's和Double's 我相信。
func propertyNameFor(inout item : AnyObject) -> String{
let listMemAdd = unsafeAddressOf(item)
let propertyName = Mirror(reflecting: self).children.filter { (child: (label: String?, value: Any)) -> Bool in
if let value = child.value as? AnyObject {
return listMemAdd == unsafeAddressOf(value)
}
return false
}.flatMap {
return $0.label!
}.first ?? ""
return propertyName
}
var mutableObject : AnyObject = object
let propertyName = MyClass().propertyNameFor(&mutableObject)
它比较对象属性的内存地址,并查看是否有匹配。 它不适用于Int's Float和Double的原因,因为它们不属于任何对象类型,尽管你可以将它们作为任何对象传递,当你这样做时转换为NSNumbers。因此内存地址会发生变化。 they talk about it here.
对于我的应用程序,它根本不会阻碍我,因为我只需要它来进行自定义类。所以也许有人会觉得这很有用。如果任何人都可以使用其他数据类型工作,那将非常酷。
答案 5 :(得分:1)
这有效:
struct s {
var x:Int = 1
var y:Int = 2
var z:Int = 3
}
var xyz = s()
let m = Mirror(reflecting: xyz)
print(m.description)
print(m.children.count)
for p in m.children {
print(p.label as Any)
}