AnyObject
AnyObject는 모든 클래스가 암묵적으로 준수할 수 있는 프로토콜이다. AnyObject는 타입이 정해지지 않은 객체에 사용할 수 있다. 모든 클래스, 클래스 타입 또는 클래스 전용 프로토콜의 인스턴스는 AnyObject를 타입으로 사용할 수 있다.
let label: UILabel = UILabel()
let button: UIButton = UIButton()
let imageView: UIImageView = UIImageView()
let a: AnyObject = label
let b: AnyObject = a.self
let c = button.self
let array: [AnyObject] = [ label, button, imageView.self ]
protocol Protocol: AnyObject { }
AnyObject는 Objective-C 클래스의 타입으로 사용할 수 있다. (Int, Double, String은 struct 타입이라 AnyObject 타입이 될 수 없다.)
let nsstr: NSString = "hello world"
let anystr: AnyObject = nsstr
print(anystr is NSString) // true
let nsnum: NSNumber = 123
let anynum: AnyObject = nsnum
print(anynum is NSNumber) // true
AnyObject를 사용한 동적 타입 변수를 Int, Double, String과 같은 타입으로 변환하려면 타입 캐스팅 연산자(as, as? as!)를 사용해야 한다.
as?
를 사용해서 조건부 타입 캐스팅을 할 수 있다.
let nsstr: NSString = "hello world"
let anystr: AnyObject = nsstr
if let message = anystr as? String {
print("Successful cast to String: \(message)")
}
캐스팅하려는 타입에 대한 정보를 알고 있는 경우 강제로 다운 캐스팅할 수 있다. 강제 캐스팅이기 때문에 잘못된 타입으로 변환되면 런타임 에러가 발생한다.
let nsstr: NSString = "hello world"
let anystr: AnyObject = nsstr
let message = anystr as! String
print("Successful cast to String: \(message)")
let failcasting = anystr as! Int // runtime error
switch문에서 as
를 이용해 캐스팅할 수 있다.
let label: UILabel = UILabel()
let button: UIButton = UIButton()
let imageView: UIImageView = UIImageView()
let array: [AnyObject] = [ label, button, imageView.self ]
for elem in array {
switch elem {
case let object as UILabel:
print("\(object) is UILabel")
case let object as UIButton:
print("\(object) is UIButton")
default:
print("\(elem) is not UILabel and Button")
}
}