jane1choi / TIL

Today I Learned #심야아요

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Swift] Any와 AnyObject

jane1choi opened this issue · comments

타입캐스팅에 대해 정리하며,

타입 캐스팅을 수행할 때 상속 관계에 있는 클래스끼리만 캐스팅이 가능하지만
Any와 AnyObject 타입을 사용할 경우, 상속 관계가 아니어도 예외적으로 사용할 수 있습니다.

라고 정리했는데요, Swift의 범용 타입인 AnyAnyObject에 대해서도 정리해보려고 합니다!

Any

  • Swift의 모든 데이터 타입을 지칭하는 키워드입니다.
  • 변수 또는 상수의 데이터 타입이 Any로 지정되어 있다면 그 변수 또는 상수에는 어떤 종류의 데이터 타입이든지 상관없이 할당 가능합니다.

Swift는 타입에 민감한 언어입니다.

스크린샷 2022-06-18 오전 12 02 19

그렇기 때문에 선언한 타입 외에 다른 타입의 데이터를 저장하려고 한다면, 위와 같이 에러가 발생하게 됩니다.

그런데, Any를 사용하면 모든 타입을 저장할 수 있습니다!
위의 코드에서 [Int]를 [Any]로 바꾸면,

스크린샷 2022-06-18 오전 12 23 04

이렇게 여러 타입의 데이터를 저장할 수 있게 됩니다.
Value 타입(일반적인 자료형을 포함한 구조체, 열거형), Reference 타입(클래스, 클로저) 모두 저장이 가능합니다!
정리하자면, Any는 모든 타입을 포함할 수 있는 범용 타입입니다.

AnyObject

  • 모든 클래스 타입을 지칭하는 프로토콜입니다.
  • 클래스의 인스턴스만 할당 가능합니다.

위에서 정리한 Any가 모든 타입을 저장할 수 있었다면,
타입이 AnyObject로 선언될 경우, 클래스 타입만 저장할 수 있다는 점에서 차이가 있습니다.

스크린샷 2022-06-18 오전 12 21 18

위와 같이 클래스 타입인 인스턴스를 제외하고 모두 에러가 발생하는 것을 확인할 수 있습니다!

⚠️ 주의할 점

Any나 AnyObject 타입으로 선언된 변수의 실제 타입은 런타임 시점에 결정됩니다.

var name: Any = "eunju"

위와 같이 name 이라는 변수를 Any 타입으로 선언했어도 우리는 name이 String 타입이라는 것을 알 수 있습니다.
하지만, name에 String의 메서드나 프로퍼티에 접근할 수 없습니다..

스크린샷 2022-06-20 오후 11 49 00

따라서, Any 타입으로 선언된 상수나 변수를 String과 같이 다른 타입으로 사용하고 싶다면,

if var name = name as? String {
    name.append(" hi")
}

위와 같이 as나 as?를 이용해 다운캐스팅 해준 후에 사용해주어야 합니다!
그렇기 때문에 범용 타입이라고 남용하지 않고 꼭 필요한 상황에서만 사용해주는 것이 중요하겠네요!!

참고 자료: Taehyeon-Kim/Blog#62, https://babbab2.tistory.com/128