본문 바로가기
iOS_Swift 앱개발👍

[iOS_Swift] 타입 캐스팅(Type Casting)의 모든 것 _ 21

by 개발하는윤기사 2022. 8. 18.
728x90
반응형

안녕하세요! 개발하는 윤기사입니다!

 

iOS 앱 개발을 하다 보면 as / as? / as! 같은 타입 캐스팅을 자주 봐오셨을 텐데요. 왜 쓰는지 잘 몰랐었습니다..

 

그래서 오늘 포스팅은 타입 캐스팅에 대해서 준비를 해왔습니다!

 

바로 시작해 볼까요?

 

- Type Casting - 

 

Swift Language Guide에 따르면

1. 타입 캐스팅은 인스턴스의 타입을 확인
2. 인스턴스를 같은 계층(hierachy)에 있는 다른 superclass나 subclass로 사용
3. 타입 캐스팅에는 is와 as 두 연산자를 사용
4. 타입 캐스팅을 이용하면 특정 프로토콜을 따르는지(conforms) 확인할 수 있음

 

<is>는 어떤 클래스의 인스턴스 타입인지, 어떤 데이터 타입인지 확인을 할 수 있는 연산자이고

 

<as>는 as / as? / as! 3가지로 나뉩니다! 그중 다운 캐스팅인 as? 와 as!, 업 캐스팅인 as로 나뉩니다.

 

Upcasting인 as는 컴파일러가 캐스팅에 대한 성공을 확신할 수 있는 경우에 사용되고 일반적으로 부모 클래스의 타입인 것을 알고 있을 때 사용됩니다.

 

그에 반해 DownCasting은 부모 클래스 타입을 자식 클래스 타입으로 다운해서 캐스팅하는 것을 뜻합니다.

 

as? : 옵셔널 반환 타입을 반환, 다운 캐스팅이 성공할 경우 옵셔널이 아닌 인스턴스가 반환이 되고, 만약 실패할 경우 nil값을 반환합니다.

as! : 옵셔널을 반환 불가. 다운 캐스팅을 성공할 경우 옵셔널이 아닌 인스턴스가 반환이 되고, 실패할 경우에는 런타임 에러가 발생합니다.

 

 

Mobile이라는 Class를 하나 만들어서 예시를 보여드리겠습니다!

클래스 선언

 

위와 같이 Mobile이라는 클래스 안에는 name과 introduce를 가지고 있고, Google 클래스 하나, Apple 클래스 하나씩을 만들어서 Mobile클래스를 상속받게 하겠습니다. 추가적으로 Apple 클래스 안에는 wwdc라는 상수를 하나 추가적으로 만들어주었습니다.

 

 

is 연산자의 활용 예시

 

그렇다면 Apple 클래스와 Google 클래스는 다 Mobile의 상속을 받고 있기 때문에 Mobile 클래스 안에 있는 name에 접근을 할 수 있습니다. is 연산자를 시용해서 확인해볼 수도 있습니다!

 

 

 

아래와 같은 예시도 한 번 보겠습니다!

let iphone

상수 iphone을 Mobile 클래스 타입을 정해놓으면, Apple클래스 name에 접근을 할 수는 있지만, 상수 iphone을 Mobile 클래스 타입이라고 선언을 해버리면 Apple 클래스 안에 있는 프로퍼티에는 접근이 불가능합니다! 

 

만약 Apple 클래스의 wwdc 상수에 접근해서 사용하고 싶다면 다운캐스팅을 해주면 됩니다!

상수 value를 Apple 클래스로 as? 연산자를 이용해서 다운 캐스팅해주면 wwdc에 접근할 수 있습니다!

 

하지만 iphone이 Apple 클래스로 사용하고 있는데 Google 클래스로 다운 캐스팅을 할 순 없습니다.

WHY? ) Mobile 클래스를 타입으로 정해놓았고, 그렇기 때문에 다른 서브 클래스인 Google에 다운 캐스팅할 수가 없는 거지요!

 

만약 iphone as! Google을 선언하면 어떻게 될까요?

 

iphone은 Apple과 Mobile 클래스로 타입이 정해져 있기 때문에 런타임 오류가 발생한답니다!

 

 

-  Any, Anyobject의 Type Casting - 

 

  • Any : 함수 타입을 포함해 모든 타입을 담을 수 있습니다. (구조체, 열거형, 클래스, 클로저 등 모든 타입)
  • AnyObject : 모든 클래스 타입의 인스턴스만 담을 수 있습니다.

 

두 가지 다 여러 타입에 대해 대응할 수 있습니다.

 

또 두 타입 모두 어떤 타입으로 된 요소를 가지고 있는지는 컴파일 시점에 알 수 없으며,

런타임 시점에 타입이 결정되기 때문에 타입 캐스팅을 하지 않으면 각 멤버에 대한 접근도 불가능합니다!

 

 

Any타입의 예제입니다!

things라는 Any타입 배열을 선언해 여러 타입의 값을 저장합니다. 여기에는 Int, String, 함수, 클로저까지 포함됩니다.

 

Any 타입의 예제

 

🍎 things를 for_in문으로 순회하며 타입 캐스팅이 되는지 switch case문에 as 연산자로 확인해 타입 캐스팅되는 배열의 원소의 값을 적절히 출력할 수도 있습니다. 이 결과, 튜플과 함수도 Any타입에 포함될 수 있다는 것을 확인할 수 있습니다!

튜플과 함수도 Any에 포함되어있다!

 

이상 오늘 포스팅은 여기서 마치겠습니다!

 

타입 캐스팅은 정말 중요하니 꼭 꼼꼼히 보셨으면 좋겠습니다 :)

 

윤기사는 오늘도 빡코딩하겠습니다 😎

 

 

 

 

참고문서: https://jusung.gitbook.io/the-swift-language-guide/language-guide/18-type-casting

 

타입캐스팅 (Type Casting) - The Swift Language Guide (한국어)

library가 갖고 있는 Movie,Song인스턴스의 공통 부모는 MediaItem이기 때문에 library는 타입 추론에 의해 [MediaItem] 배열의 형을 갖게 됩니다. library를 순회(iterate)하면 배열의 아이템은 Movie, Song 타입이

jusung.gitbook.io

 

728x90
반응형