unowned vs unowned(safe) vs unowned(unsafe)
unowned를 사용하는 방법은 아래처럼 총 세가지가 있습니다.
- unowned
- unowned(safe)
- unowned(unsafe)
대부분 unowned만 사용하며 나머지는 크게 사용할 일이 없습니다. 그렇다면 나머지 2개는 왜 존재할가요?
우선은 각각에 대해 먼저 알아보겠습니다.
unowned(safe)
unowned(safe)는 참조를 사용할 때 런타임 safety checker가 먼저 검사를 수행합니다. 런타임 safety checker는 사용하는 메모리가 실제 사용하는 객체가 맞는지를 확인합니다. 참조한 객체가 해제가 되어 더이상 메모리가 유효한 객체가 아니라면 런타임 safety checker에 의해 즉시 런타임 오류가 발생합니다.
unowned(unsafe)
unowned(safe)는 참조를 사용할 때 런타임 safety checker가 비활성화됩니다. 참조한 객체가 해제된 후에 사용하면 대부분 런타임 오류가 발생하지만 발생하지 않고 정상동작이나 엉뚱한 동작을 할 수 있습니다. 런타임 safety checker에 의해 메모리를 조사하지 않기 때문에 해당 주소가 동일한 클래스의 객체로 변경되면 그 객체에서 정상동작을 할 수 있으며 다른 객체로 메모리가 교체되었다면 예상하지 못한 엉뚱한 동작을 할 수도 있습니다. 그래서 안전하지 않다고 표현하는 것입니다. unowned(unsafe)를 사용하려면 사용하는 사람이 안전하게 동작하도록 모든 책임을 가져야합니다.
unowned
unowned는 대부분의 경우 unowned(safe)와 동일하게 동작을 합니다. 다만, 컴파일할 때 옵션에 -Ofast를 설정하면 unowned(unsafe)로 동작합니다. Int가 32 bit에서는 4byte로 동작하고 64bit에서는 8byte로 동작하는 개념과 비슷하다고 할 수 있습니다.
각각에 대해서 알아보았습니다. 이제 unowned가 세가지인 이유에 대해서 알아보겠습니다.
- unowned(safe)는 컴파일 설정에 따라 다르게 동작하는 것이 아니라 명시적으로 항상 런타임 safety checker를 활성화시키기 위해서 사용합니다.
- unowned(unsafe)는 성능상 향상을 위해서 사용합니다. 런타임시에 메모리를 조사하는 동작이 없기 때문에 성능향상이 있을 수 있습니다. 또한, objective-c와의 호환성을 위해서도 필요합니다. objective-c에서 property를 unsafe_unretained나 assign으로 설정했을 때 swift에서 동일하게 동작하는 것이 unowned(unsafe)입니다.
- unowned는 일반적인 경우에는 safe로 동작하게 하고 컴파일 옵션을 다르게 했을 때에는 unsafe로 동작시킬 때 사용할 수 있습니다. 대부분unowned만을 사용합니다.
참고
댓글
댓글 쓰기