2016-07-22 3 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, 개체를 사전으로 "번역"하는 편리한 방법이 있습니까? 이 jict를 json으로 웹 서비스에 전달해야합니다. 이것이 진정한 목적입니다. – user3352185

+1

이 객체가 NSObject 파생물 인 경우 Objective-C 런타임에 인트로 스펙 션하도록 요청할 수 있습니다. 순수 스위프트에는 편리한 방법이 없습니다. 개인적으로 나는 한 번에 하나의 속성으로 손으로 변환을 작성합니다. – 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/사전에 대한 직접 변환을 사용하는 일부 성능 테스트와 프로토콜 비교를 비교하고 미러를 사용하여 프로토콜 확장을 수행합니다. – 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 초인지 신경 쓰지 않기를 바랍니다.