2017-12-11 3 views
0

제 코드에서 SWXMLHash 라이브러리를 사용하여 일부 XML을 deserialize하고 있습니다. 해당 .value() 메서드는 사용자 지정 deserialise 함수와 마찬가지로 선언에 throws 키워드가 있습니다.Swift : 오류가 try 문을 무시합니다.

내가 다음 코드 줄이 있습니다 때 노드

extension UInt8: XMLElementDeserializable { 
    public static func deserialize(_ element: XMLElement) throws -> UInt8 { 
     return UInt8(element.text)! 
    } 
} 

이 작동 : 라이브러리가 UInt8에 대한 디시리얼라이저가 포함되어 있지 않습니다

let myValue : UInt8 = try? xml["Root"]["ValueNode"].value() 

이후를, 나는 내 자신을 정의한 가치가있다. 그러나 노드가 존재하지 않거나 nil 인 경우 다음 줄에서 오류가 발생합니다.

return UInt8(element.text)! // Fatal error: Unexpectedly found nil while unwrapping an Optional value 

이것은 분명히 발생합니다. 내가 이해하지 못하는 이유는이 오류가 내 try? 문에 걸리지 않고 해당 오류를 던지는 대신 nil을 반환하는 이유입니다.

아무도 도와 줄 수 있습니까?

+0

'throws '와'try'를 사용하면 치명적인 오류를 처리 할 수 ​​없습니다. 치명적입니다. optional을 다루기 위해서는 Swift에 적절한 방법이 내장되어 있습니다. – rmaddy

+0

이전에 꽤 많이 다루어졌습니다. https://stackoverflow.com/a/37222884/2976878, https://stackoverflow.com/a/38738365/2976878, https : // stackoverflow.com/q/46866311/2976878, https://stackoverflow.com/q/31335023/2976878 & https://stackoverflow.com/q/43009744/2976878. – Hamish

답변

1

모든 오류를 신속하게 발견 할 수있는 것은 아닙니다. throws 키워드를 사용하여 함수를 표시하면 해당 함수가 을 복구 가능 오류로 던질 수 있음을 나타냅니다. 그러나 사용자 지정 구현은 실제로 오류를 throw하지 않습니다. throw 키워드로 표시되고 코드 throw Error을 사용하여 던져진 기능에서만 던진 오류는 do-catch 블록에 의해 catch 될 수 있습니다.

try?은 throwable 함수의 반환 값을 선택적으로 변환하는 방법입니다. 함수가 오류를 던지면 try? 뒤에 오는 값은 nil이되고, 그렇지 않으면 값은 선택적입니다.

!을 사용할 때 컴파일러에게 무엇을하고 있는지 알리고 특히 !을 사용한 작업이 실패하면 응용 프로그램이 정상적으로 실패하지 않아야합니다.

deserialize 메서드를 변경하여 선택적 unwrapping을 적절하게 처리하거나 throw 및 오류를 처리해야합니다.

extension UInt8: XMLElementDeserializable { 
    public static func deserialize(_ element: XMLElement) throws -> UInt8 { 
     if let val = UInt8(element.text) { 
      return val 
     } else { 
      throw NSError(domain: "Couldn't deserialize value to UInt8", code: 1) 
     } 
    } 
} 
1
return UInt8(element.text)! 

이 줄에는 try이 없습니다. 따라서 여기서 오류가 발생하지 않습니다. UInt8이 주어진 문자열을 변환 할 수없는 경우 nil을 반환합니다. 그리고 나서, 물론 !nil을 충돌로 만듭니다. 대신 그

대신 같은 것을 할 : 일반적으로

guard let retVal = UInt8(element.text) else { throw SomeError } 
return retVal 

: !를 사용하여 뭔가를 할 수있는 방법, 그리고 !를 사용하지 않고 같은 일을 할 수있는 또 다른 방법이 때, 두 번째 갈 당신이 정말로 좋은 이유가 없다면 하나.

관련 문제