본문 바로가기

Swift

Swift에서 애매한 옵셔널의 처리

옵셔널은 틀림없이 Swift의 가장 중요한 기능 중 하나이며 Objective-C와 같은 언어와 구분되는 핵심 요소이다. 

nil이 올수 있는 경우를 사전에 처리하므로, 우리는 보다 정확하게 오류를 예방할 수 있는 코드를 작성할 수 있다.


우리는 옵셔널을 배우면서 가능하면(?) 옵셔널 타입을 강제로 해제 하지 말라고 배웠지만,

실재로 많은 예제를 볼때에도 옵셔널 타입을 강제하는 경우를 종종 볼 수 있다.





이거 절대로 하지말라며 ????????????????????????????




위 예제는 테이블 뷰를 선언하는 예제인데 테이블 뷰가 옵셔널 타입으로 선언된 것을 볼 수 있다.


문제는 해당 테이블 뷰를 사용할때 guard나 if문을 써서 안전하게 옵셔널을 해제하지 않는다는 것이다.


하지만 viewDidLoad 함수처럼 서브 뷰로 테이블 뷰를 설정해야 하는 부분에서,


백만분의 일 확률로 guard나 if 문으로 테이블 뷰의 옵셔널을 제거하다 nil이 발생을 하면?


이런 코드는 말이 안되는 코드이며(테이블 뷰를 쓸건데 테이블 뷰가 없어?) 

코드의 구조를 추론하는것이 매우 어렵게 되기 때문에 바람직한 코드라고 보기가 힘들다.







그럼 테이블 뷰 변수는 반드시 옵셔널 타입으로 생성되어야 하는가?



정답은 아니다. 이럴경우 사용할 수 있는 방법이 바로 lazy 이다. 


lazy는 게으르다는 의미로 변수를 "지금 당장 초기화 하지 않고 선언"할 수 있는 방법으로 응용할 수 있다.







테이블 뷰를 lazy로 선언하게 되면 어떤일이 발생할까? 위의 코드를 한글로 풀어보면




"tableView 변수를 사용할 건데 지금 당장 초기화 하지는 말고 실재로 변수가 사용될때 초기화를 해라"




라는 의미정도로 해석될 수 있다.


즉 tableView 변수는 변수가 선언될때 초기화 되는 것이 아니라 viewDidLoad 함수가 실행되면서 frame을 설정할때 실재로 초기화가 된다.


이렇게하면 코드내에서 옵셔널 타입을 깔끔하게 제거할 수 있다!






정상적으로 좀더 잘생긴(?) 크래쉬 발생 시키기



Json 파일을 로드한다고 생각해보자. 이 경우 파일의 값이 nil일 수 있기때문에 nil일 경우에 대한 처리가 필수적이다.


우리는 보통 이런경우에도 옵셔널을 사용해서 nil값이 들어오는 경우를 처리할 수 있다.


let Configuration = loadConfiguration()!



만일 위와 같이 처리를 한다고 가정해보자. 

만일 위 변수를 선언하는 도중에 nil 이 들어왔지만 옵셔널을 해제하려하면,


오류가 발생하면서 아래와 같은 메세지를 보여준다.


fatal error: unexpectedly found nil while unwrapping an Optional value





이런 오류는 큰 단점이 하나 있는데 오류에 대한 상세 정보를 알려주지 않는다는 것이다. 우리가 오류를 보고 알 수 있는 사실은 단지 옵셔널 값을 강제로 열었다가 문제가 발생했다는 사실 하나 뿐이다.





이럴경우 guard문과 preconditionFailure() 함수를 조합한 효과적인 해결법이 존재한다.





위와 같이 코드를 작성할 경우 오류 메세지는 아래와 같이 변경된다.



fatal error: Configuration couldn’t be loaded. Verify that Config.JSON is valid.: file /Users/John/AmazingApp/Sources/AppDelegate.swift, line 17





자 우리는 이제 정확하게 어디서 오류가 발생했는지 알 수 있게되었다!












출처 : https://medium.com/@johnsundell/handling-non-optional-optionals-in-swift-e5706390f56f