2017-06-29 33 views
2

在我的應用程序中,我將自定義類中的對象轉換爲字典,以便它們可以在本地保存在plist以及服務器上。我使用以下方式將類的屬性轉換爲字典:檢查是否計算或存儲變量

func dictionary() -> [String : Any] { 

    var count: UInt32 = 0; 
    let myClass: AnyClass = self.classForCoder; 
    let properties = class_copyPropertyList(myClass, &count); 

    var dictionaryRepresentation: [String:Any] = [:] 

    for i in 0..<count { 
     let property = properties![Int(i)] 
     let cStringKey = property_getName(property); 
     let key = String(cString: cStringKey!) 

     dictionaryRepresentation[key] = self.value(forKey: key) as Any 
    } 

    return dictionaryRepresentation 
} 

但是,我有一個計算屬性的問題。看起來這些是計算出來的,並且返回的值也被放入字典中,我想避免這些值。所以這裏是我的問題:

是否有可能檢查是否是一個只使用其名稱編程計算的屬性?

我假設這可能是通過試圖給它分配一個值,它會給我一個錯誤或一些類似的方法。

+1

[使用鏡像API應該有幫助](https://appventure.me/2015/10/24/swift-reflection-api-what-you-can-do/)。您無法從計算出的屬性中分辨存儲的屬性,但通過將可設置的屬性與只讀屬性區分開來,您會非常接近。 – dasblinkenlight

+0

這樣會很好,但是通讀之後我不確定如何區分。我必須仔細看看。無論如何,謝謝你的建議,它看起來很有希望。 –

+0

看起來像鏡像只是忽略計算屬性,所以這是如何做出區分,只需通過所有的孩子,他們都是可以設置的。謝謝! –

回答

1

根據dasblinkenlight的建議,這似乎是一個工作解決方案。

不是使用上面概述的Objective-C方法,而是創建一個Mirror類,該類具有由所有可設置屬性組成的children,因此不包括可計算屬性。

像這樣來使用:

let mirror = Mirror(reflecting: MyObject) 

for case let (label?, value) in mirror.children { 
    print (label, value) 
} 

這裏的標籤是變量和值的名稱明顯的價值。

編輯:如果有人想將對象轉換爲字典,我在這裏發佈完整的代碼。但是請記住,如果值也是自定義對象,那麼也需要進行轉換。

func dictionary() -> [String:Any] { 
    let mirror = Mirror(reflecting: self) 

    var dictionaryRepresentation = [String:Any]() 

    for case let (label, value) in mirror.children { 

     guard let key = label else { continue } 

     dictionaryRepresentation[key] = value 
    } 

    return dictionaryRepresentation 
} 
0

您可以嘗試property_copyAttributeList(_:_:)函數,它可能包含swift的計算屬性的只讀標記。雖然我猜let屬性也會有這個標記,所以你必須找到一種方法來區分它們。

相關問題