[Swift] 타입 캐스팅 (Type Casting)
타입 캐스팅은 인스턴스의 타입을 확인하거나 어떠한 클래스 인스턴스를 해당 클래스 계층 구조의 슈퍼 클래스나 서브 클래스로 캐스팅하는 방법입니다.
Swift 에서 타입 캐스팅은 is
와 as
연산자로 구현됩니다. 이 두 연산자는 값의 타입을 확인하거나 값을 다른 타입으로 캐스팅하는 간단한 방법을 제공합니다.
타입 캐스팅을 이용하여 타입이 프로토콜을 준수하는지 확인할 수도 있습니다.
타입 캐스팅을 위한 클래스 계층 정의
클래스 및 서브 클래스들의 계층 구조와 타입 캐스팅을 이용한다면 특정 클래스 인스턴스의 타입을 확인하고 해당 인스턴스를 동일한 계층 구조 내의 다른 클래스로 캐스팅할 수 있습니다.
위의 코드에는 MediaItem
이라는 클래스와, 이를 상속받는 Movie
Song
클래스가 정의되어 있습니다.
library
에는 Movie
클래스와 Song
클래스의 인스턴스들이 들어있습니다. 이렇게 되면 library
의 타입은 Array<MediaItem>
이 됩니다. 이때 만약 타입을 Movie
나 Song
으로 이용하고 싶다면 타입을 확인하거나 해당 타입으로 다운 캐스트해서 사용해야 합니다.
타입 검사
is
연산자를 사용하면 인스턴스가 특정 서브 클래스 타입인지 확인합니다. 만약 인스턴스가 서브 클래스 타입이면 true
를, 그렇지 않다면 false
를 반환합니다.
위의 코드는 library
의 아이템들의 타입을 하나씩 검사하고 있습니다. library
의 아이템들은 MediaItem
타입을 가지고 있지만, 반복문 내에서 is
연산자를 통해 해당 아이템이 서브클래스인 Movie
타입인지, Song
타입인지 확인할 수 있습니다.
다운캐스팅
특정 클래스 타입의 상수와 변수는 서브 클래스의 인스턴스를 참조할 수 있습니다. 이 조건을 만족할 경우 타입 캐스트 연산자 as?
as!
를 이용해 서브 클래스 타입으로 다운캐스트 할수 있습니다.
다운캐스트는 실패할 수 있으므로 2가지 형태의 연산자가 제공됩니다.
as?
연산자는 다운캐스트하려는 타입의 옵셔널값을 반환합니다. 따라서 다운캐스트가 실패할 경우 nil
을 반환합니다.
as!
연산자는 다운캐스트를 시도하고 반환된 옵셔널값을 강제로 언래핑합니다. 따라서 다운캐스트가 실패할 경우 런타임 에러가 발생합니다.
그렇기 때문에 다운캐스트의 성공이 불확실하다면 as?
연산자를 활용하는 것이 좋습니다.
위에서 사용했던 클래스들로 다시 예를 들어보겠습니다. 위의 코드는 MediaItem
타입의 인스턴스를 다운캐스트하고 있습니다. 이 경우 각 아이템에 대하여 Movie
타입인지 Song
타입인지 알 수 없기 때문에 as?
연산자를 사용하는 것이 안전합니다.
조건이 만족된다면 movie
와 song
에는 알맞은 클래스 타입의 인스턴스가 할당됩니다. 캐스팅은 실제로 인스턴스를 수정하거나 값을 변경하지는 않고, 인스턴스는 동일하게 유지되지만 캐스트 된 타입의 인스턴스로 처리됩니다.
Any 와 AnyObject 에 대한 타입캐스팅
Swift 는 타입이 정해지지 않은 2개의 특별한 타입을 제공합니다.
- Any : 함수 타입을 포함한 모든 타입의 인스턴스를 나타낼 수 있음
- AnyObject : 클래스 타입의 인스턴스만 나타낼 수 있음
이는 굉장히 편리하지만, 실제 작업에 사용될 타입을 구체적으로 지정하는 것이 가장 좋습니다.
things
배열에 다양한 타입의 값들이 추가되었습니다. 이는 things
의 타입이 Array<Any>
이기 때문인데, 이러한 경우 모든 항목에 대해 특정 타입을 찾고 싶다면 switch
문의 case
에서 is
as
연산자를 사용할 수 있습니다.
참고 링크
https://docs.swift.org/swift-book/LanguageGuide/TypeCasting.html
https://icksw.tistory.com/57?category=876233
'iOS 개발 > Swift' 카테고리의 다른 글
[Swift] GCD & Dispatch Queue (2) | 2022.05.27 |
---|---|
[Swift] 싱글톤 패턴 (Singleton Pattern) (0) | 2022.05.20 |
[Swift] 프로토콜 (Protocols) (0) | 2022.05.13 |
[Swift] 확장 (Extensions) (0) | 2022.05.13 |
[Swift] ARC (2/2) (0) | 2022.04.29 |