본문 바로가기

Swift 공부

타입캐스팅 is , as 와 Any , AnyObject

is , as를 알기위해 우선 MediaItem 클래스를 생성합니다.

class MediaItem {
    var name: String
    init(name: String) {
        self.name = name
    }
}

 

그 후 MediaItem 을 서브클래스로 가지는 Movie 와 Song 클래스를 만듭니다.

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)
    }
}

배열을 하나 만들어 줍니다.

 

let library = [
    Movie(name: "Casablanca", director: "Michael Curtiz"),
    Song(name: "Blue Suede Shoes", artist: "Elvis Presley"),
    Movie(name: "Citizen Kane", director: "Orson Welles"),
    Song(name: "The One And Only", artist: "Chesney Hawkes"),
    Song(name: "Never Gonna Give You Up", artist: "Rick Astley")
]

 

 

let library : [MediaItem] = [
    Movie(name: "Casablanca", director: "Michael Curtiz"),
    Song(name: "Blue Suede Shoes", artist: "Elvis Presley"),
    Movie(name: "Citizen Kane", director: "Orson Welles"),
    Song(name: "The One And Only", artist: "Chesney Hawkes"),
    Song(name: "Never Gonna Give You Up", artist: "Rick Astley")
]

이렇게 보여줄수도 있습니다.

 

배열을 for 문을 통해 is 와 as 를 사용해보겠습니다.

Is 예제

var movieCount = 0
var songCount = 0

for item in library {
//배열을 돌면서 item의 클래스가 Movie라면 movieCount가 증가
    if item is Movie {
        movieCount += 1
//배열을 돌면서 item의 클래스가 Song라면 songCount가 증가
    } else if item is Song {
        songCount += 1
    }
}

결과는 

 movieCount = 2
 songCount = 3

이렇게 is를 통해 아이템의 인스턴스의 타입을 확인할 수 있다.

 

As 예제

for item in library {
    if let movie = item as? Movie {
        print("Movie: \(movie.name), dir. \(movie.director)")
    } else if let song = item as? Song {
        print("Song: \(song.name), by \(song.artist)")
    }
}

 

As를 통해 item이 Movie or Song 으로 변경이 가능해진다면 인스턴스의 타입을 변경 할 수 있습니다.

여기서 as? 를 해준 이유는 해당 아이템이 형변환이 가능할수도 불가능할수도있기때문에 as? 를 채용하게 됩니다

만약 여기서 as!를 사용하게된다면 형변환이 불가능한것을 시도했기때문에 바로 죽어버립니다 ㅜㅜ

 

 

 

이렇게 보면 말로는 잘 모르겠다. 역시 백문이 불여일견이라고 직접 한번 해보는게 최고의 효율이지 않을까

 

let AnyArray : [Any] = ["1",1,1.0,123]

Any를 이용해 String , Int , Double이 담겨있는 배열을 만들수 있었다.

Any를 AnyObject로 변경하게되면

어쩌구 저쩌구의 에러가 나온다

번역을 해보면 더 많은 맥락이 없으면 표현 유형이 모호합니다.

그럼 에러를 없앨려면 어떻게 해야하나

 

let AnyObjectArray : [AnyObject] = [ ("1" as AnyObject) , (1 as AnyObject) ,
(1.0 as AnyObject) , (123 as AnyObject)]

 이렇게 변경을 하게되면 에러 메세지가 사라지게 된다 AnyObject가 도대체 뭐길래 이렇게되는걸까?

 

AnyObject를 타고들어가게되면

AnyObject의 공식설명

그렇다 AnyObject는 모든 클래스가 암시적으로 준수하는 프로토콜이였다.

 

String , Int , Double 등은 Struct이기때문에 AnyObject배열에 준수하지 못하였던거였다.

 

이정도로 is , as , Any , AnyObject를 알아보고 글을 정리한다.

'Swift 공부' 카테고리의 다른 글

Swift MVVM  (0) 2022.03.09
Protocol Oriented Programming(POP) - With RxSwift Mvvm  (0) 2022.02.18
WKWebView MemoryLeak 해결  (0) 2021.11.12
Swift 함수형 프로그래밍  (1) 2021.08.05
Moya / RxMoya 사용해보기  (2) 2021.08.01