관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 예외처리로 리펙토링하기 (throw, try, catch) 본문

Refactoring (리펙토링)

[iOS - swift] 예외처리로 리펙토링하기 (throw, try, catch)

jake-kim 2023. 12. 17. 21:42

예외처리

  • throw를 하고 사용하는쪽에서 try - catch하는 예외처리를 모르는 개발자는 없지만 예외처리를 잘 활용하는 방법을 깨닫는것도 중요
  • swift에서 보통 메서드를 작성하다가 특정 상황에서는 guard문을 사용한다거나 if문을 사용하여 특정 부분에서만 동작하도록 하는 것이 대부분

예외처리의 중요성

  • 확장성 증가
    • 보통 메서드나 함수를 작성할 때 특정 기능이 필요해서 만드는데, 이렇게 되면 메서드 내부에서 예외적인 사항들을 guard문이나 if문으로 처리하는데 이렇게 처리하게 된다면 특정 상황에서만 사용할 수 있는 코드로 존재

ex) 인수로 들어오는 view의 subview들을 대상으로 UIStackView의 색상을 추출해내는 함수

func getStackViewColor(parentView: UIView) -> UIColor? {
    let targetView = parentView
        .subviews
        .first { $0 is UIStackView }
    
    return targetView?.backgroundColor
}
  • return 타입이 Optional이므로 컬러가 있으면 해당 컬러값을 얻어내고, 컬러값이 없다면 nil을 리턴해주는 함수
  • 당장 사용하는쪽에서는 stackView의 backgroundColor만 필요한 상황이므로 이렇게해도 만족하여 사용할 수 있지만, 추후에 color가 없거나 UIStackView가 없는 상황들에 대해서 별도의 처리가 필요한경우 이 함수를 변경해야하는 상황이 발생
  • 반면 아래처럼 throws를 작성하면 사용하는 쪽에서 예외처리가 필요하면 수행하고 필요없으면 사용하지 않게끔 인터페이스를 열어두어 확장성있는 코드 유지가 가능
enum ViewStateError: Error {
    case nonExisted
    case nonColor
}

func getStackViewColorNew(parentView: UIView) throws -> UIColor {
    let targetView = parentView
        .subviews
        .first { $0 is UIStackView }
    
    guard let targetView else { throw ViewStateError.nonExisted }
    guard let color = targetView.backgroundColor else { throw ViewStateError.nonColor }
    return color
}

사용하는 쪽)

do {
    let stackViewColor = try getStackViewColorNew(parentView: view)
} catch {
    switch error as? ViewStateError {
    case .nonExisted:
        print("nonExisted")
    case .nonColor:
        print("nonColor")
    case .none:
        print("none")
    }
}
}
  • 하지만 예외처리를 하게된다면 try 키워드를 붙여주어야하므로 공통으로 사용되지 않는 코드라면 예외를 제공해주지 않게하여 코드의 유연함도 챙기기

정리

  • 현재 필요한 메서드를 구현하려고 할 때, 여러곳에서 공통으로 사용할 수 있는 여지의 코드라면 Optional을 리턴해주지 말고 예외처리를 할 것 (확장성 제공)

* 전체 코드: https://github.com/JK0369/ExEceptionRefactor

Comments