2014-09-23 25 views
30

所以我想在Swift中得到實際的變量名稱作爲字符串,但還沒有找到一種方法來做到這一點...或者我正在看着這個問題和解決方案壞角度。得到一個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 

然而,這給出了變量本身內部或變量類型的信息,在這種情況下是變量字符串,我希望變量的實際名稱。

+0

實際上你想通過變量的名稱實現什麼?這不是JavaScript或Python。像那些動態語言在運行時保持這種信息。在Swift中,變量名對程序員來說純粹是一種方便(以便爲存儲地址提供人名),並且它們在運行時不存在於程序中。 – Alexander 2017-06-07 16:51:50

回答

14

由於每從this answer更新,則在夫特3經由#keyPath

NSPredicate(format: "%K == %@", #keyPath(Person.firstName), "Andrew") 
+0

我會成爲大壩......謝謝你的擡頭。由於語言的新穎性,我擔心這一點。嗯有什麼辦法可以做這種映射? – 2014-09-23 22:29:55

+0

哦,謝謝我在編輯之前輸入了上面的聲明。非常感謝您的關注。 – 2014-09-23 22:30:22

+0

如果您需要屬性或變量元數據,您將不得不自己處理它。 – ColinE 2014-09-23 22:30:37

0

支持的最佳解決方案是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; 
} 

}

+1

此解決方案不會給出父項中的屬性名稱類。對? – vivin 2016-01-08 21:30:03

0

我想出了一個swif t解決方案,但不幸的是它不適用於Int的Float和Double的我相信。

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的Float和Double,因爲它們不屬於anyobject類型,儘管你可以將它們作爲anyobject傳遞,當你這樣做的時候它們會被轉換爲NSNumbers。因此內存地址改變。 they talk about it here.

對於我的應用程序,它並沒有阻止我,因爲我只需要它用於自定義類。所以也許有人會覺得這很有用。如果任何人都可以使用其他數據類型進行工作,那麼這將非常酷。

NSPredicate(format: "%K == %@", #keyPath(Person.firstName), "Wendy") 

編輯 - 在斯威夫特4我們卻有更好:

+0

我總是會得到「」空字符串,當我執行我的域類變量時...你能幫我調試因爲我對鏡子和其他東西沒有更深的理解嗎? @david rees – vivin 2016-01-08 21:49:10

+0

當你說域類變量是什麼意思?如果你不給我一個例子,我無法幫助你。 – 2016-01-11 23:27:45

+0

通過域對象我的意思是,Java bean類/傳輸對象類.. – vivin 2016-01-13 03:06:53

42

這是正式斯威夫特3使用#keyPath()

https://github.com/apple/swift-evolution/blob/master/proposals/0062-objc-keypaths.md

用法示例看起來像支持:

NSPredicate(format: "%K == %@", \Person.mother.firstName, "Wendy") 

// or 

let keyPath = \Person.mother.firstName 
NSPredicate(format: "%K == %@", keyPath, "Andrew") 

速記是一個值得歡迎的補充,並且能夠引用來自變量的關鍵路徑非常強大

+0

謝謝我的英雄!我只想說通過這個#keyPath()的用法,可以使2個方法'value(forKeyPath:)'和'setValue(_,forKeyPath)'啓用更改。 IMO這應該是Swift 3新接受的答案。 – Tulleb 2016-08-01 12:09:20

+0

這個例子中的變量名稱是什麼,它作爲字符串發送/給出的地方是什麼? – Confused 2016-11-20 23:15:30

+0

「變量」根本不是變量。這是在代碼中的其他位置定義的類/結構。就像'class Person {let firstName:String}'。如果這個例子看起來很奇怪,我建議閱讀[NSPredicates](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html),當它們非常強大時使用集合 – Andrew 2016-11-25 23:54:19