- 계산 속성
"계산 속성이 아닌 방식"으로 구현예시
class Person {
var name: String = "사람"
var height: Double = 160.0
var weight: Double = 60.0
func calculateBMI() -> Double {
let bmi = weight / (height * height) * 10000
return bmi
}
}
let p = Person()
p.height = 165 // 키 165
p.weight = 65 // 몸무게 65
p.calculateBMI() // 23.875
// BMI를 계산하는 이 산식은 파라미터가 없고,
// 내부에 가지고 있는 저장 속성값을 이용해, 계산한 후 결과값을 리턴한다.
위의 코드를 계산속성(Computed Properties)으로 바꾸어서 구현하기
class Person {
var name: String = "사람"
var height: Double = 160.0
var weight: Double = 60.0
var bmi: Double {
get { //getter ===> 값을 얻는다는 의미
let bmi = weight / (height * height) * 10000
return bmi
}
// set(bmi) { //setter ===> 값을 세팅한다(넣는다)는 의미
// weight = bmi * height * height / 10000
// }
set { // newValue 라는 파라미터로 쓰기로 (생략 가능)
weight = newValue * height * height / 10000
}
}
// 만약에 쓰기 계산속성(set)을 메서드로 구현했다면
// func setWeightWithBMI(bmi: Double) {
// weight = bmi * height * height / 10000
// }
}
let p1 = Person()
p1.height = 165 // 키 165
p1.weight = 65 // 몸무게 65
p1.bmi // 23.875
p1.bmi = 25
p1.bmi // 25
- 항상 다른 저장 속성에 의한 결과로 계산해 나오는 그런 방식의 메서드인 경우 아예 속성처럼 만들 수 있다. (===> 계산 속성)
- 계산 속성 ===> 구조체, 클래스, (열거형) 동일
- 항상 변하는 값이므로, var로 선언해야함 (let로 선언불가)
- 자료형 선언을 해야함(형식추론 형태 안됨) (메서드이기 때문에 파라미터, 리턴형이 필요한 개념)
- get은 반드시 선언 해야함(값을 얻는 것은 필수, 값을 set하는 것은 선택)
- 읽기만 가능한 계산속성(read-only)은 get블록을 생략 가능
get블록만 있다면, 굳이 한번 더 감쌀 필요가 없다. ===> 편의를 위해 get을 생략가능
var bmi: Double {
let bmi = weight / (height * height) * 10000
return bmi
}
그렇다면 메서드가 아닌, 속성방식으로 구현하면 무슨 장점이 있을까?
- 관련이 있는 두가지 메서드(get, set)를 한번에 구현할 수 있다.
- 그리고 외부에서 보기에 속성이름으로 설정가능하므로 보다 명확해 보인다.
따라서, 계산 속성은 메서드를 개발자들이 보다 읽기 쉽고, 명확하게 쓸 수 있는 형태인 속성으로 변환해 놓은 것이다.
- 실제로, 계산 속성은 겉모습은 속성(변수)형태를 가진 메서드(함수)임 ⭐️
- 계산 속성은 실제 메모리 공간을 가지지 않고, 해당 속성에 접근했을때 다른 속성에 접근해서 계산한후,
그 계산 결과를 리턴하거나 세팅하는 메서드 이다. (메모리 - 메서드구조)
- 계산 타입 속성
class Circle1 {
// 저장 타입 속성
static let pi: Double = 3.14
static var count: Int = 0
// (계산) 타입 속성(read-only)
static var multiPi: Double {
return pi * 2
}
// 저장 속성
var radius: Double // 반지름
// 생성자
init(radius: Double) {
self.radius = radius
// Circle.pi = 1
}
}
let b = Circle1.multiPi // 6.28
그렇다면, 어떤 경우에 타입 속성을 선언해야 하나?
➡︎ 모든 인스턴스가 동일하게 가져야 하는 속성이거나(해당 타입의 보편적인 속성), 모든 인스턴스가 공유해야하는 성격에 가까운 경우!
계산 타입 속성 ===> 상속에서, 상위클래스에서 class키워드를 붙인 경우, 재정의 가능
- class키워드(계산 타입 속성만) ⭐️
- 상속이 있는 경우, 계산 타입 속성에서는 static대신 class키워드를 사용(===>static과 동일한 역할)하면 재정의 가능한 속성이 된다.
'iOS > Swift' 카테고리의 다른 글
메모리 누수가 발생하는 상황 : 강한 참조 사이클 + 해결방안? (0) | 2022.01.17 |
---|---|
힙 메모리 관리 - ARC 정리 (0) | 2022.01.13 |
클로저의 메모리 구조 + 캡처현상 / 캡처리스트 (2) | 2021.12.22 |
클래스&구조체 메모리 관점에서의 차이 (0) | 2021.12.17 |
[구조체&클래스] 속성 - 저장 속성, 지연(Lazy) 저장 속성, 저장 타입 속성, 속성감시자 (0) | 2021.09.10 |