2016-07-22 57 views
2

我想用一個類的屬性來製作字典。斯威夫特:鏡子(反映:自我)太慢了?

class SomeClass() { 
    var someString = "Hello, stackoverflow" 
    var someInt = 42 // The answer to life, the universe and everything 
    var someBool = true 

    func objectToDict() -> [String: String] { 
     var dict = [String: String]() 
     let reflection = Mirror(reflecting: self) 
     for child in reflection.children { 
      if let key = child.label { 
      dict[key] = child.value as? AnyObject 
     } 
     return dict 
    } 
} 

但是objectToDict()很慢。有沒有辦法加快速度,或者可能是另一種將屬性值添加到字典的方法?

+2

除了爲了從調試器讀取該值以外,您不應該進行鏡像,因此速度無關緊要。如果您正在爲其他目的進行鏡像,請備份並以另一種方式實施。 – matt

+0

@matt,有沒有方便的方法可以將對象「翻譯」爲一個字典?我需要將此詞典作爲json傳遞給Web服務,這纔是真正的目的。 – user3352185

+1

如果這個對象是一個NSObject派生物,你可以讓Objective-C運行時爲你反思。純Swift中沒有任何方便的方法。就我個人而言,我只是一次隻手寫一個屬性的轉換。 – matt

回答

0

不僅如此,它也不是一個好主意:鏡像僅用於調試內省。你應該自己構建字典。這確保了您可以靈活地以完全正確的方式存儲所有數據,並且還可以從您生成的字典的鍵中分離Swift屬性名稱。

class SomeClass { 
    var someString = "Hello, stackoverflow" 
    var someInt = 42 // The answer to life, the universe and everything 
    var someBool = true 

    func objectToDict() -> [String: AnyObject] { 
     return ["someString": someString, "someInt": someInt, "someBool": someBool] 
    } 
} 
+0

你也可以檢查這個https:// stackoverflow。com/questions/44872370 /其中我有一些性能測試使用直接轉換爲字典vs協議一致性與使用'Mirror'的協議擴展。 – valcanaia

1

我不同意其他大多數用戶。使用反射會減少代碼,這意味着開發,維護和測試產品的時間更少。有了像EVReflection這樣寫得很好的圖書館,你不必擔心場景背後的事情太多。

但是,如果性能將成爲一個問題,那麼而不是完全使用基於反射的方法。我會說在我的前端開發中這絕對不是問題,特別是在iOS中,但在後端開發中不能忽略它。要看看它有多慢,我在Xcode中運行了一些測試。我會寫一個關於它的博客,但一般來說,獲取Mirror不是最糟糕的部分(加上它可能可以捕獲內存中的屬性列表),所以用objc運行時替換它不會改變太多的情況。另一方面,setValue(_, forKey)出乎意料地緩慢。考慮到在現實生活中,您還需要執行諸如檢查dynamicType等任務,使用動態方法肯定會使其慢100倍,這對於服務器開發來說是不可接受的。

- Looping 1,000,000 times for a class with 1 `Int` property 
    - Getting mirror: 1.52 
    - Looping throw mirror and set `child.value`: 3.3 
    - Looping throw mirror and set `42`: 3.27 
    - Setting value `42`: 0.05 

再次,對於iOS我會繼續使用它來節省我的時間。希望最終客戶不會在乎它是0.005秒還是0.0005秒。