-Today's Learning Content-

  • NSInvalidArgumentException 에러

1. NSInvalidArgumentException

내용 정리

코어 데이터를 저장할 때 갑자기 발생한 에러다... 에러 메세지는 아래와 같다

'NSInvalidArgumentException', reason: '-[WeekDays count]: unrecognized selector sent to instance 0x28225a670'

이 에러가 무엇이고 왜 발생하는가?

1) NSInvalidArgumentException 발생 원인

프로젝트를 진행하며 UI를 완성하고, 코어 데이터와 연동하여 잘 작동하는지 확인하기 위해 create 메소드를 테스트 해보았는데 크래쉬가 발생하며 에러 문구가 출력되었다.

'NSInvalidArgumentException', reason: '-[WeekDays count]: unrecognized selector sent to instance 0x28225a670'

에러에서는 WeekDays의 count가 문제라는 것처럼 나오는데... WeekDays는 엔티티의 Replationships로 지정한 타입으로, count라는 메소드나 프로퍼티는 가지고 있지 않다...

처음에는 내 코드가 문제가 있는 줄 알고 코드를 이리저리 고치며 빌드 테스트를 했지만 해결이 되지 않았다.
그래서 문제를 해결하기 위해 여기저기 도움을 구해 해결을 구했는데...

결론부터 말하자면 내 코드의 문제는 아니었다.

이 에러는 Core Data 모델의 To-One 관계(단방향 관계)에서만 발생하는 에러이며, Xcode의 버그라고 한다.

에러가 발생하는 원인은 특정 엔티티(여기서는 WeekDays)가 관계 속성에서 count 메소드를 호출하는 것이다.
이는 Core Data 모델의 관계 설정 중 To-Many 관계에서 Ordered 속성을 유지한 채 To-One 관계로 변경했을 때 발생할 수 있다고 한다.

그럼 어떻게 해결할 수 있을까?

2) 에러 해결 방법

이러한 에러를 해결하기 위해서는 아래와 같은 순서를 따라야 한다.

  1. 문제가 되는 관계 찾기
    • Core Data 모델에서 문제가 되는 관계(Relationships)를 식별한다.
    • 관계가 To-One으로 설정되어 있는지 확인한다.(아닐 경우 다른 방법으로 해결해야 함)
  2. 설정을 변경하기
    • 해당 관계의 타입을 To-Many로 변경한다.
    • Ordered 속성을 비활성화 한다.
    • 다시 To-One 관계로 변경한다.

위의 2단계를 따르는 것으로 문제를 해결할 수 있다.
실제로 나도 위의 단계를 거쳐서 무사히 빌드를 성공시킬 수 있었는데, 무척이나 허탈했다...

이러한 버그는 Core Data 모델링에서 관계를 변경할 때, 관계의 타입을 단순히 To-Many에서 To-One으로 변경하면 Ordered 속성이 비활성화 되지 않고 남아있어서 발생한다고 한다.

이로 인해 Xcode가 XML 내부에 Ordered 속성을 YES로 유지하는 잘못된 코드를 생성하게 되고, 이는 런타임에서 예상치 못한 동작을 유발하여 앱에 크래쉬가 발생하게 되는 것이다.

XML 예시

  1. To-Many Ordered(정상적인 경우)
<relationship name="foo" toMany="YES" ordered="YES" destinationEntity="SomeEntity" deletionRule="Nullify" syncable="YES"/>
  1. To-One (버그가 발생하는 경우)
<relationship name="foo" maxCount="1" ordered="YES" destinationEntity="SomeEntity" deletionRule="Nullify" syncable="YES"/>
  1. To-One (정상적인 경우)
<relationship name="foo" maxCount="1" destinationEntity="SomeEntity" deletionRule="Nullify" syncable="YES"/>

3) 추가 팁

위와 같은 문제를 해결하기 위해 Core Data에서 엔티티들의 관계를 삭제하고 동일한 이름으로 다시 생성할 수도 있지만, XML의 동작 원인을 이해하면 이런 불필요한 작업을 줄일 수 있다.

또, Git 변경 로그를 통해 어떤 설정이 변경되었는지 추적하여 문제의 근본 원인을 찾아보는 것도 문제를 빠르게 해결하는데에 도움이 될 수 있다.

4) 결론

Xcode가 처음으로 별로라고 느껴졌다.

-Today's Lesson Review-

이런 경우는 처음 겪어봐서 많이 당황했다.
앞으로는 잘 확인하고 진행해야지...
profile
이유있는 코드를 쓰자!!

0개의 댓글