3월11일 TIL (프로퍼티 옵저버, 타입캐스팅)

이승원·2024년 3월 11일
0

TIL

목록 보기
33/75
post-thumbnail

프로퍼티 옵저버 (Property Observer)

  • 프로퍼티 옵저버는 프로퍼티를 관찰하여 특정 프로퍼티의 값 변경 전후에 추가 동작을 수행할 수 있다
  • 저장 프로퍼티 (Stored Propety), 연산 프로퍼티 ( Computed Property)에서만 사용 가능.

willset

  • willset은 프로퍼티 값이 변경되기 직전에 호출, newValue를 통해 변경될 값 접근 가능.

didset

  • didset은 프로퍼티 값이 변경된 직후에 호출, oldValue를 통해 변경되기 전의 값 접근 가능.

willset vs didset

  • 둘 다 작성이 되어 있는 경우, 당연히 willset 먼저 호출
var temp = 10 {
    willSet{
    	//temp 값이 변경되기 직전에 호출 
        print("값이 \(newValue) 로 변경될 예정입니다.")
    }
    didSet {
    	//temp 값이 변경된 직후에 호출
        print("값이 \(oldValue)에서 \(temp) 로 변경되었습니다.")
    }
    
}
temp = 20

타입 캐스팅 (Type Casting)

  • 변수나 객체의 타입을 다른 타입으로 변환하는게 타입 캐스팅이다.

is

  • 변수나 객체의 타입을 체크하는 연산자, 반환값은 boolean이다.
let integer : Int = 30
let boolean : Bool = true
let array : [String] = []

print(integer is Int) // true
print(boolean is String) // false
print(array is [String]) // true
  • 깊게 생각해야 할 점은, 만약 특정 인스턴스가 자식 클래스의 타입을 갖고 있고, 부모클래스로 is로 확인을 하여도, true를 반환한다.
let integer : Int = 30
print(integer is Int) // true
print(integer is Any) // true
// Int 는 Any의 하위클래스다.

as, as!, as?

  • 인스턴의 타입을 확인하거나, 해당 인스턴스를 슈퍼 클래스 (부모 클래스)나 하위 클래스 (자식 클래스)로 취급하는 방법
  • 상속관계에서의 인스턴스과 타입의 대한 정리가 필요하다
// Person은 슈퍼 클래스(부모 클래스)
class Person {

}

// Student는 서브 클래스(자식 클래스) - 상속받은 클래스
class Student: Person {

}

let person: Person = Person() - 가능
let person: Student = Person() - 불가능
let student: Person = Student() - 가능
let student: Student = Student() - 가능
  • 위 코드는 Person 이 부모 클래스이며, Student가 자식 클래스다. 자식 클래스의 인스턴스는 부모 클래스의 타입을 갖을 수 있으나, 부모 클래스의 인스턴스는 자식 클래스의 타입을 갖을 수 없다.
  • 예시에서의 코드를 쉽게 설명하자면, 학생을 사람으로 취급할 수 있지만, 모든 사람을 학생으로 취급할 수 없다. 뭐 이런식으로 접근하면 편할꺼 같다. 물론 이건 해당 예시에서만 가능한 생각방밥이지만.
  • 아래 표를 보고 as, as?, as!의 차이를 알아보자.
연산자실행단계반환 값캐스팅 방향
as컴파일 단계인스턴스 or Fail업 캐스팅
as?런타임 단계옵셔널 타입 인스턴스 or nil다운 캐스팅
as!런타임 단계인스턴스 or Runtime Error다운 캐스팅
  • 아래 예시 코드를 통해 조금 더 이해가 될 수 있다.
class Person {
    var id = 0
    var name = "name"
    var email = "hgk@gmail.com"
}

class Worker: Person {
    // 현재 상속 받은 property
    // id
    // name
    // email
    var salary = 300
}

class Programmer: Worker {
    // 현재 상속 받은 property
    // id
    // name
    // email
    // salary
    var lang = "Swift"
}

let person1 = Person()
let worker1 = Worker()
let programmer1 = Programmer()

let personList : [Person] = [person1, worker1, programmer1]
// 자동으로 상위 클래스인 person으로 업 캐스팅이 된 상황
// 즉 모든 요소들이 Person 타입으로 갖고 있음.
personList[1].name // "name"
//personList[2].salary
//오류, worker1은 원래 Worker 타입을 갖고 있었지만, array에 넣으면서 자동 업캐스팅 됨.
//즉, 현재는 worker1은 Person 타입
print(type(of: personList[0])) // Person
print(type(of: personList[1])) // Worker
print(type(of: personList[2])) // Programmer

let temp1  = personList[1] as Person // 타입캐스팅 성공, 단, salary 접근 불가.
//let temp2 = personList[1] as Worker // 오류 as는 업캐스팅용이고, 현재 personList[1]은 Person 타입
let temp3 = personList[1] as! Worker // 타입캐스팅 성공, personList[1]가 원래 worker 인스턴스였으니까 가능.
//let temp4 = personList[0] as! Worker // 오류, personList[0]은 원래 person 인스턴스, 하위 클래스로 타입캐스팅 불가.
if let temp5 = personList[1] as? Worker {
    print(temp5.salary)
}

profile
개발자 (진)

0개의 댓글