Stop on Objective-C Exceptions

by Eonil

Xcode에는 Stop on Objective-C Exceptions라는 옵션이 있습니다. 처음에 이 옵션을 보고  멋모르고 이걸 켰다가 지금까지 고생을 했네요.

일단, 이 옵션은 로우레벨 예외에서 멈추는 옵션입니다. Cocoa는 Objective-C의 예외를 캐치해 적절한 예외 메시지를 생성해 보여줍니다.

그런데 이 옵션을 체크하면 예외가 생성된 그 순간에 디버거가 멈춥니다. 그래서 예외 메시지가 전혀 표시되지 않고 EXC_BAD_어쩌구 하는 메시지나 SIGABRT만 보이게 됩니다. 최악의 경우에는 아무것도 안나옵니다.

로우 레벨 개발을 지원하기 위해 존재하는 옵션인거죠. 더 강력한 기능에 엑세스할 수 있도록 하는 옵션이지만, 평소에는 쓸 일이 없습니다.

예외 메시지 없이 디버깅하기…

너무 힘들었었습니다. 로우레벨 옵션을 켜놓고 지금까지 코코아에 원래 예외 메시지가 없는 줄 알았던 겁니다! 생각해보면 말이 안되는 거죠. 플랫폼 시스템용 API인데 예외 메시지가 전혀 없다는 건 있을 수 없는 일입니다. 그런데도 그려러니 하고 넘어갔던 건 이상한 프레임워크를 너무 많이 봐와서일겁니다.

이 문제를 발견하게 된 것은 Fast Enumeration 덕분입니다. for…in으로 컬렉션을 조회하고 있는데 조회문에서 계속 예외가 발생하는 거죠.

for(id <Discrete> e in elements)    // 여기에서 예외
{
    [e tick];
}

메시지도 없고, 모든 요소들을 다 검사해봐도 문제가 없었습니다. 4시간 정도를 고민하다가 그냥 잠들어버렸습니다. 좀 자다가 일어나서 다시 이걸 쳐다보니 조회 도중에 컬렉션을 수정하고 있다는 것이 생각났습니다. C#의 for…in에서는 조회 중 컬렉션을 수정하면 예외가 생겼죠. 곧바로 이런 기본적인 예외에 대한 메시지조차 표시하지 않는 이유가 뭘까? 하는 생각이 들었습니다. 그리고 예외 메시지가 없을리가 없다는 생각을 하게 됐죠. 그리고 생각난게 Stop on Objective-C Exceptions 옵션입니다.

생각난 김에 바로 이 옵션을 끄고 테스트를 해 봤죠.

‘컬렉션 조회 중 컬렉션을 수정하였기에 예외가 발생했습니다’라는 문구가 보이시나요? 제가 4달 동안 보고 싶었던 것도 이겁니다. 정말 반가워요! 지금가지의 어려웠던 세월이 힘겹게만 느껴집니다…

더 놀라운것은 이 옵션을 켰더라도 이 메시지를 볼 수 있다는 겁니다. 그냥 디버깅 컨티뉴를 하면 됩니다.

그러면 옵션을 켜지 않았을 때와 마찬가지의 메시지를 보여줍니다.

물론 경우에 따라서 그냥 종료되는 경우도 있는데, 그런 경우는 정말로 해당 예외에 대한 메시지가 없는 경우이겠죠. 또한, 어떤 경우엔, 안좋아 보이는 로그가 계속 뜨는데 예외로 잡히지 않는 경우도 있습니다. 이 경우엔 이 옵션을 켜야만 예외가 잡힙니다.

기본 세팅

처음 이 옵션을 봤을 때, Xcode가 여러 언어를 지원하므로 Objective-C에 특화된 기능인지 알고 그냥 켰습니다. 물론 왜 기본으로 꺼져 있을까… 하는 의심이 있긴 했지만요. 덕분에 지금까지 예외 메시지 하나 없이 계속 개발을 했던 것이죠. 플렉스 빌더같은 이클립스 계열은 뭔가 많이 세팅해주지 않으면 제대로 작동하는게 없을 지경이라 버릇대로 했던 것이 이런 결과를 불러왔습니다.

역시 애플의 성향대로, 기본 세팅이 최적의 세팅이었습니다. 웬만해서는 아무것도 건드리지 않는 것이 좋습니다.

결과적으로 이 옵션은 정말 로우 레벨입니다. 강력한 대신 불친절하죠. 일단 한동안 옵션을 끄고 사용해봐야겠습니다. 필요할 때만 켜서 쓰도록 말이죠.