だから私はSwiftで実際の変数名を文字列として取得しようとしていますが、それを行う方法を見つけていません...またはこの問題と解決策を間違った角度で見ています。
だからこれは基本的に私がやりたいことです:
var appId: String? = nil
//This is true, since appId is actually the name of the var appId
if( appId.getVarName = "appId"){
appId = "CommandoFurball"
}
残念ながら、Apple docsでこれに近いものを見つけることができませんでしたが、これは次のとおりです。
varobj.self or reflect(var).summary
ただし、これにより、変数自体の内部の情報またはこの場合の変数のタイプがStringであるという情報が得られ、変数の実際の名前が必要になります。
この回答 から更新されたとおり、Swift 3 via #keyPath
NSPredicate(format: "%K == %@", #keyPath(Person.firstName), "Andrew")
これは、Swift 3で#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")
速記は歓迎すべき追加であり、変数からキーパスを参照できることは非常に強力です
これは私の解決策です
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
最良の解決策は ここ です
指定されたリンクから
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;
}
}
Swift解決策を思いつきましたが、残念ながらはInts、Floats、およびDoubles 私は信じている。
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)
オブジェクトのプロパティのメモリアドレスを比較し、一致するものがあるかどうかを確認します。 Ints、Floats、Doublesがanyobject型ではないため機能しない理由。ただし、これらをNSNumbersに変換すると、anyobjectとして渡すことができます。したがって、メモリアドレスが変更されます。 彼らはここでそれについて話します
私のアプリでは、カスタムクラスにのみ必要なため、まったく邪魔になりませんでした。だから誰かがこれを役に立つと思うかもしれません。誰かが他のデータ型でこれを機能させることができれば、それはかなりクールです。
これは動作します:
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)
}