GGURUPiOS

[Swift] AnyObject, AnyClass, Any 에 대해 알아보기 본문

Swift/문법 파헤치기

[Swift] AnyObject, AnyClass, Any 에 대해 알아보기

꾸럽 2023. 11. 1. 17:37

안녕하세요.

이번시간에는 AnyObject, Any, AnyClass 에 대해 알아보도록 하겠습니다.

저것들을 이용해서 직접적으로 짜본적은 없지만 Swift 내장 메서드들을 사용할 때 가끔 저런녀석들이 보이는데요.

저 아이들을 파헤쳐 보겠습니다.

 


 

AnyObject?

공식문서에 따르면, AnyObject는 모든 클래스들이 암묵적으로 준수하는 프로토콜 이라고 되어있습니다.

모든 클래스 인스턴스, 클래스 타입 또는 class-only 프로토콜에 대한 타입으로 사용될 수 있다고 합니다.

 
예제를 살펴봅시다.

class FloatRef {
    let value: Float
    init(_ value: Float) {
        self.value = value
    }
}


let x = FloatRef(2.3)
let y: AnyObject = x
let z: AnyObject = FloatRef.self

y의 타입은 AnyObject를 준수하는 타입으로 되어있기 때문에

FloatRef 인스턴스를 할당한 x를 y에 할당해도 되는것입니다.

 

z의 경우에 AnyObject는 인스턴스가 아닌 클래스 타입 자체로도 사용이 될 수 있으므로, FloatRef.self를 써도 문제가 없습니다.

 

AnyObject의 타입 캐스팅

타입이 AnyObjct인 객체는 동적 타입을 유지하며 캐스팅 연산자(as, as?, as!) 를 사용해서 해당 타입으로 캐스팅 할 수 있다고 한다.

예제를 보자.

let s: AnyObject = "This is a bridged string." as NSString
print(s is NSString)
// true
if let message = s as? String {
    print("Successful cast to String: \(message)")
}

그런데 한가지 궁금증이 생긴다. 

NSString은 클래스이고, String은 구조체로 이루어져있다. 어떻게 타입캐스팅이 되는걸까요?

 

그건 바로 Bridge를 통해 가능하게 한다고 한다.
서로 다른 프로그래밍언어, 데이터 형식, 플랫폼 또는 기술 사이에서 상호작용을 가능하게 한다고 한다.

즉 말 그대로 다리의 역할인것 같다.

 

Objective-C와 Swift간에는 브리지가 존재하고, 이것을 통해 서로 상호작용 할 수 있다고 함

형변환의 경우 더 자세히 알아보면 ObjectiveCBridgeable 프로토콜이 있고

이 프로토콜을 채택하면 Swift 타입을 참조 타입으로 형 변환하기 위한 맞춤형 메커니즘을 제공한다고 한다.


더 자세한 내용은 아래 출처에서 확인할 수 있다
https://github.com/apple/swift/blob/main/docs/DynamicCasting.md

 

우리는 AnyObject에 대한 대략적인 것들을 알아보았습니다.

그러면 AnyClass 는 무엇일까요?


AnyClass?

공식문서에 따르면, AnyObject는 모든 클래스 타입이 암묵적으로 준수하는 프로토콜 이라고 되어있습니다.

즉 AnyObject와는 달리, 클래스의 인스턴스나 class-only 프로토콜에 대한 타입은 안되고

클래스 타입의 객체를 의미하는것만 가능하다는 말입니다.

 

 

 


Any?

함수 타입을 포함하며 모든 타입의 인스턴스를 나타낼 수 있다고 합니다.(물론 타입 자체를 나타낼수도 있음)

 

AnyObject와 마찬가지로 형변환이 됩니다. 

그 외 내용은 AnyObject와 비슷하기에 따로 기술 하지 않겠습니다.

 


고려할 점, 언제 쓸까요? 

공부 해봤을 때, AnyObject와 Any 타입은 유연함을 제공하는 것으로 보입니다.

 

그러나 결국 우리가 앱을 만들 때, 매번 타입 체크 혹은 형변환을 해서 사용해야 하기 때문에 번거로울 것입니다.

(String을 Any타입으로 저장해버린다면, 우리는 String안에 내장되어있는 메서드를 못씀)

 

만약 그럼에도 써야한다면 switch문을 통해 아래와 같이 쓸 수 있도록 합시다

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)")
    default:
        print("something else")
    }
}

 


출처

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/typecasting/

 

Documentation

 

docs.swift.org

https://medium.com/@mimicatcodes/any-vs-anyobject-in-swift-3-b1a8d3a02e00

 

Any vs. AnyObject in Swift 3.0

When I encountered these two type aliases while parsing JSON data for the first time, I had no idea how to distinguish or implement them…

medium.com

https://github.com/apple/swift/blob/main/docs/DynamicCasting.md

https://ios-development.tistory.com/600

 

[iOS - swift] Self vs self (대문자 Self와 소문자 self)

소문자 self 인스턴스 자체 접근 시 사용되는 참조값 self는 참조 타입 value type에서의 self는 stack영역에 존재하는 instance를 가리키는 형태 reference type에서의 self는 heap 영역에 존재하는 instance를 가

ios-development.tistory.com