욤찌의 개발 일기
[Swift] Any랑 AnyObject 공부했다. 근데 TypeCasting을 곁들인,,(2) 본문
Any와 AnyObject를 공부하려다가 타입캐스팅 글로 끝나버린 지난 글,,(머쓱)
그래서 이제 진 짜 공부하려던 Any랑 AnyObject에 대해 쭈절대본다
이 친구들을 알기 위해서는 왜 타입캐스팅을 공부했어야만 했는지가 오늘의 관전포인트
💡Any와 AnyObject에 대해 설명하시오.
1) Any는 무엇인가
Any can represent an instance of any type at all, including function types.
Any는 함수타입을 포함하여 모든 타입의 인스턴스를 나타낼 수 있다.
모든 타입에는 위에서 언급한 함수타입을 포함해서 구조체, 클래스, 열거형, 옵셔널 등 모~든 타입을 다 나타낸다.
진짜 모든 타입을 다 포함할 수 있다고?
옼케이. 그럼 진짜 다 넣어봄
var things: [Any] = []
공식문서의 예제를 가져와봤움
things 라는 변수가 있는데 타입은 Any의 배열임.
그래서 온갖 타입을 한 번 다 넣어보겠음
things.append(0) // 1번 Int
things.append(0.0) // 2번 Double
things.append(42) // 3번 Int
things.append(3.14159) // 4번 Double
things.append("hello") // 5번 String
things.append((3.0, 5.0)) // 6번 (Double, Double)
things.append(Movie(name: "친절한 금자씨", director: "박찬욱")) // 7번 class
things.append({ (name: String) -> String in "Hello, \(name)" }) // 8번 함수타입
Int, Double, String(구조체), 튜플, class, 함수타입을 다 넣었더니
에러가 날까여 ?????
ㄷㄱㄷㄱㄷㄱㄷㄱ
아~주 잘 담겨버렸습니다
오 뭐여뭐여!!!! 스위프트 강타입 언어라더니~~ 이러면 타입 걍 죄~~다 Any 쓰면 되겠구먼~!~!~!
...
이라고 생각하는 사람이 있겠쥬?(나)
너무 당연스럽게도 남발하면 절대 안 됨 ^^ ㅋ
근데 이게 된다면 타입을 왜만들었겠음? 왜 스입푸드가 강타입언어겠음??!!
안되는 이유는 일단 AnyObject도 보고 난 후에 알아봅시당
2) AnyObject는 무엇인가
AnyObject can represent an instance of any class type.
Any는 아까 모든 타입을 다 넣을 수 있다고 했자나유?
근데 AnyObject는 그 중에서도 class의 인스턴스만 나타낼 수 있음!
오호? 그렇다면 다시 확인 ㄱㄱㄱ
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)
}
}
let mediaItem1: MediaItem = MediaItem(name: "영화")
let movie1: Movie = Movie(name: "친절한 금자씨", director: "박찬욱")
var anyObjectArray: [AnyObject] = [movie1, mediaItem1]
이전 글에서 만들었던 MediaItem, Movie 클래스임.
각각의 인스턴스를 만들어서 [AnyObject] 타입인 anyObjectArray 변수를 만들어 넣어보았다.
일단 아직까지는 에러가 나지 않는다.
클래스 타입의 인스턴스들을 담을 수 있다
자, 그렇다면 돌을 던져보겠읍니다
오호! 난다난다 에러가 난다!!
20이라는 Int 타입, 그러니까 구조체의 인스턴스를 넣었더니 뭔가 표현식의 타입이 모호하다는 에러가 났다.
그런데 AnyObject 라는 타입을 공부해 본 기억이 없는 것 같아서,, 공식문서 찾아보니까
AnyObject는 바러바러 프 로 토 콜 이라고 함
오호 그렇다
왜 클래스만 되는가 했더니 !!!
The protocol to which all classes implicitly conform.
모든 클래스들이 암묵적으로/절대적으로 채택하고 있는 프로토콜이라고 함 !!!!
근데 왜 클래스 타입이 꼭 채택해야 하는 프로토콜인거지?그것도 써있더라구여 ~ ㅋ
You use AnyObject when you need the flexibility of an untyped object or when you use bridged Objective-C methods and properties that return an untyped result. AnyObject can be used as the concrete type for an instance of any class, class type, or class-only protocol.
Objective-C 와의 상호운용성을 강화하기 위해서 그렇다고 하는군용!
3) 그래서 Any랑 AnyObject는 어떻게 써야할까
Any와 AnyObject가 모든 타입을 or 클래스 타입의 인스턴스들을 나타낼 수 있다고는 했지만
그렇다고 이 친구들 타입만 쓸 수 없다.
var str: Any = "안녕하세요 스트링입니다 믿어주세요"
str이라는 변수를 하나 만들었는데 거기에는 누가봐도 String 타입인 문자열을 할당했다.
그런데 일단 타입은 Any라고 지정했다.
근데 어차피 할당된게~ 문자열이니까~ 당연히 문자열처럼 쓸 수 있겠지~~? 생각했지만 ,, 😞
아무리 문자열을 할당해도 해당 변수의 타입은 Any이기 때문에 String 타입에 접근해서 사용할 수가 없음.
그렇기 때문에 Any는 모든 타입의 인스턴스를 나타낼 수는 있으나 접근은 불가한거임 ㅜ
그래서 !!!!!
이럴려고 !!!!! 타입캐스팅 공부함 !!!!!!!
그래서 Any 를 다운캐스팅 해서 해당 타입으로 사용해줘야함 !!!!!!
as? (혹은 as!) 연산자를 이용해서 다운캐스팅 해야만 해당 타입으로 사용할 수 있음
그래서 예시에서 str을 String으로 다운캐스팅 해야~ String의 메서드에 접근이 가능합니당
그리고 as 연산자 공부할 때 왜 이걸 몰랐찌??? 했던게 ,, 업캐스팅도 가능하지만 패턴 매칭도 가능하다고 함!!
그래서 Any 타입의 인스턴스들을 switch 문에서 as 연산자 (혹은 is 연산자) 로 타입매칭으로 분기처리도 해줄 수 있음!
공식문서 예제가 좋아서 가져와볼게옹 (귀찮은거 아님)
for thing in things {
switch thing {
case 0 as Int:
print("zero as an Int")
case 0 as Double:
print("zero as a Double")
case let someInt as Int:
print("an integer value of \(someInt)")
case let someDouble as Double where someDouble > 0:
print("a positive double value of \(someDouble)")
case is Double:
print("some other double value that I don't want to print")
case let someString as String:
print("a string value of \"\(someString)\"")
case let (x, y) as (Double, Double):
print("an (x, y) point at \(x), \(y)")
case let movie as Movie:
print("a movie called \(movie.name), dir. \(movie.director)")
case let stringConverter as (String) -> String:
print(stringConverter("Michael"))
default:
print("something else")
}
}
아까 맨~~ 위에서 언급했던 온갖거 다 넣었던 things 배열을 분기처리 했숩니다
결과는
(넘 당연)
+) ‼️아 그리고 참고한 블로그에서 구조체의 인스턴스를 AnyObject로 업캐스팅하니까 오류가 없어진 것을 보고
나도 정수 타입(구조체)인 20을 AnyObject로 업캐스팅을 했더니 ..!
뭐여 ..? 클래스만 된다며 ..!!! 웅성웅성👥👤👥뭐야..👤👥👥👤👥👥👤수군수군… 이게 왜 되지? ㄴㅇㄱ
넘나 놀라워서 찾아보았더니 ,, 이것 또한 공식문서에 있었따,,~ (머쓱)
AnyObject can also be used as the concrete type for an instance of a type that bridges to an Objective-C class. Many value types in Swift bridge to Objective-C counterparts, like String and Int.
이것도 아까 AnyObject를 사용하는 이유였던 Objective-C와의 연결성과 관련이 있는데
Swift에서 정수 20은 구조체이지만 Swift 내부적으로 Int와 같은 일부 기본 타입(like String)을 Objective-C의 NSObject 타입을 상속하는 NSNumber와 같은 클래스로 취급하기도 한다고 함! 옵젝씨와의 연결성 그리고 편의성을 위한 Swift의 기능 중 하나라고 합니댜
그래서 20을 옵젝씨의 NSNumber로 간주해서 업캐스팅이 되었던 것이었읍니다 !!! 짱신기 !!!!!!!!
우와 ~~~ 드디어 ~~~~ 타입캐스팅과 Any, AnyObject에 대한 공부 및 정리 끗~~~
진짜 평소에 넘 궁금하기도 했고,, 이렇게 알고나니까 속 시 ~ 원 ~ 개비스콘 ~ 넘 재밌다 !!!!!!
다음에는 또 어떤걸 공부해볼까 ~ 정.말.기.대.된.다..^^
잘못된 정보가 있다면 언제든지 지적 부 탁 드 려 용 🥰
📖 reference(늘 감사합니당) ♥️
Documentation
docs.swift.org
https://developer.apple.com/documentation/swift/anyobject
AnyObject | Apple Developer Documentation
The protocol to which all classes implicitly conform.
developer.apple.com
https://babbab2.tistory.com/128
Swift) Any와 AnyObject 알아보기
안녕하세요 :) 소들입니다! 오늘은 타입 캐스팅의 연장선으로 Any AnyObject 라는 "범용" 타입에 대해 공부해보려고 해요!! 모든 포스팅은 편의 말투로 합니다~!! 1. Any & Any Object 타입 캐스팅을 수행할
babbab2.tistory.com
https://zeddios.tistory.com/213
Swift ) Any와 AnyObject의 차이
안녕하세요 :) Zedd입니다. 오늘은 Any와 AnyObject의 차이를 알아볼거에요!! 시작할게요!! Any와 AnyObject의 차이 The Swift Programming Language에서, Any와 AnyObject를 이렇게 말합니다. Swift는 특정하지 않은 타
zeddios.tistory.com
'Swift' 카테고리의 다른 글
[Swift] 내가 알던 Subscripts가 아녀 (0) | 2023.11.04 |
---|---|
[Swift] Any랑 AnyObject 공부했다. 근데 TypeCasting을 곁들인,,(1) (3) | 2023.11.03 |
[Swift] 나는 그저 Convenience Initializers 가 알고싶었을 뿐인데,,~ (0) | 2023.11.01 |
[Swift] Class 성능 높이는거,, 그거 어떻게 하는건데,, (1) | 2023.10.31 |
[Swift] ARC(Auto Reference Counting) (2) (0) | 2023.07.17 |