2021. 11. 6. 18:23ㆍSwift, iOS Foundation
오늘 다룰 내용은 iOS 개발을 하다가 누구나 쉽게 마주칠 수 있는 is, as, as?, as!이다.
이런 표현을 통틀어서 Swift에서는 "타입 캐스팅(Type Casting)"이라 부르는데,
Swift에서 타입 캐스팅은 '해당 인스턴스의 타입이 무엇인지?'
혹은 '해당 인스턴스를 부모 타입 혹은 자식 타입처럼 사용할 수 있는지?'를 처리하기 위해 사용된다.
여기서 결론부터 말하자면, 전자의 내용은 is로, 후자는 as를 사용해 표현하게 될 것이다. 자세한 내용은 아래 글을 따라 계속 읽어보자.
1. is : 해당 인스턴스가 우측의 타입에 해당하는지?
다시 언급하자면, is는 해당 인스턴스의 타입이 무엇인지
즉, "너는 정말 이 타입에 해당하니?"에 대한 대답을 얻고자 할 때 사용된다.
(인스턴스) is (타입)
// 해당 인스턴스가 우측의 타입에 해당하는지 아닌지 true/false로 반환
// Bool값을 반환하므로, if문/switch문을 활용해 다채롭게 표현할 수 있음
// 예제
// item들의 색을 반복해서, item이 특정 타입일 때마다 해당 변수를 1씩 증가시킴
var redCount = 0
var blueCount = 0
for item in bag {
if item is Red {
redCount += 1
} else if item is Blue {
blueCount += 1
}
}
2. as : 자식 클래스를 부모 클래스로 업캐스팅해주기
업캐스팅 as는 자식 클래스를 부모 클래스 인척 해주는 키워드다.
자식 클래스는 항상 부모 클래스를 상속 받은 애이므로 어쩌면 굳이 필요 없이(?) 대부분 생략 가능하다.
업캐스팅은 간략하게만 읽고, 뒤에 있을 다운캐스팅을 더 꼼꼼히 읽어보자.
(자식 클래스 인스턴스) as (부모 클래스 인스턴스)
// UniversityStudent 인스턴스를 생성하여, Person 행세를 할 수 있도록 업 캐스팅
var minjae: Person = UniversityStudent() as Person
// UniversityStudent 인스턴스를 생성하여, Any 행세를 할 수 있도록 업 캐스팅
var minjae: Any = UniversityStudent() // UniversityStudent() as Any 생략가능
3. as? : 형 변환이 가능할 수도, 가능하지 않을 수도 있다!
이미 Swift에서 물음표 '?'가 가지는 의미를 배워본 적이 있다.
바로 값이 있을 수도, 없을 수도 있음을 의미하는 옵셔널(Optional)이었다.
그럼 형 변환을 뜻하는 as와 불확실성을 의미하는 물음표 '?'가 만난다면?
형 변환이 가능할 수도, 가능하지 않을 수도 있음을 의미하게 된다.
이런 조건 때문에 'as?'를 "조건부 다운 캐스팅"이라 부른다.
옵셔널을 배울 때, 옵셔널로 반환된 값은 일반 타입과 구분되고, 이를 일반 값처럼 사용하기 위해서는 값을 꺼내는 과정(언래핑)이 필요하다고 했던 거 기억하는가?
그래서 조건부 타입 캐스팅도 마찬가지로,
옵셔널 값을 반환하기 때문에 실제로 인스턴스를 사용하기 위해서는 언래핑 과정이 필요하게 된다.
// 예시1
class MediaItem {
var name: String
init(name: String) {
self.name = name
}
}
class Movie: MediaItem {
var director: String
init(name: String, director: String) {
self.director = director
super.init(name: name)
}
}
class Song: MediaItem {
var artist: String
init(name: String, artist: String) {
self.artist = artist
super.init(name: name)
}
}
// library라는 배열은 Movie와 Song을 모두 상속하고 있는 MediaItem 형의 배열로 정의되어 있음
let library = [
Movie(name: "어바웃 타임", director: "리처드 어쩌구")
Song(name: "지코", artist: "아는 노래")
]
// as? 사용 부분
for item in library {
if let movie = item as? Movie {
무비로 다운 캐스팅이 가능할때 나오는 부분
}
else if let song = item as? Song {
송으로 다운 캐스팅이 가능할때 나오는 부분
}
}
// 예시2
let personName: String = notification.object as? String ?? "이름"
4. as! : 강제로 형 변환 시켜줘!
물음표 '?'가 옵셔널이었다면, 느낌표 '!'는 Swift에서 강제 언래핑을 뜻했다.
타입캐스팅에서도 마찬가지이다.
형 변환을 뜻하는 as와 강제를 뜻하는 '!'가 만나면, 강제로 타입을 변경하는 "강제 다운 캐스팅"이 되는 것이다.
당연히, 이 방법은 위험도가 존재하기 때문에, 확실히 형변환이 가능한 경우에만 사용해야 하고,
만약 형변환(타입캐스팅)에 실패하게 되면, 런타임 에러를 발생하게 될 것이다.
(인스턴스) as! (클래스 네임)
// 반드시 이것은 String형으로 형변환이 성공한다
let personName: String = notification.object as! String
'Swift, iOS Foundation' 카테고리의 다른 글
[Foundation] UserDefaults를 사용해서 데이터를 전달하는 방법 (0) | 2021.12.17 |
---|---|
[Swift] 함수 앞에 private가 붙어 있던 이유, 접근 제어(Access Control) (0) | 2021.11.08 |
[Swift] 옵셔널(Optional) 완전 정복하기: 개념부터 옵셔널 바인딩까지 (0) | 2021.08.24 |
[iOS] 내가 보려고 정리하는 Coding Convention (feat. Style Share) (0) | 2021.08.17 |
[Swift] Closure 완전 정복하기: 일급 객체부터 작성법, 그리고 @escaping까지 (0) | 2021.08.12 |