과제물의 조건.
조건은 위와 같았다.
완성된 코드를 먼저 보자
import UIKit
var balance: Double = 0.0 {
willSet(newValue) {
if newValue >= 0.0 {
print("\(newValue)원을 입금하겠습니다.")
print("기존 잔액: \(balance), 입금 후 잔액: \(newValue)\n\n")
} else {
print("🚨 경고: 잔액은 음수가 될 수 없습니다. 잔액을 0원으로 설정합니다.")
balance = 0.0
print("최종 잔액: \(balance)원")
}
}
didSet {
if balance >= 0.0 {
print("입금이 완료되었습니다.")
print("현재 잔액: \(balance), 기존 잔액: \(oldValue)\n")
print("최종 잔액: \(balance)원")
}
}
}
balance = 1000
balance라는 변수를 선언하고, 데이터타입은 Double, 값은 0.0으로 선언하였다.
그리고 willSet과 didSet이라는 프로퍼티 옵저버를 사용하였다.
willSet과 didSet의 차이점은, 값을 저장하기 직전과 값을 저장한 직후 호출된다는 차이가 있다.
그리고 if문에 부합하면 print문들을 출력, 부합하지 않으면 else문으로 출력.
그다음 didSet으로 넘어가서, (값이 저장된 직후에 출력됨) if문을 통과했다면,
정상적으로 저장되었다는 것을 알리기 위해 print문을 출력!
결과물
음수를 입력하여 경고메시지가 제대로 출력되는지 확인해보자.
우여곡절
willSet과 didSet 두 곳 모두에다가 경고메시지를 넣었었다.
이렇게되면 경고메시지가 두번 출력되고 balance가 두번 초기화 되게 된다.
요런식으로 말이다.
뭔가 미완성 된 버그 투성이의 프로그램을 돌리는 기분이었고
굉장히 찝찝했다.
그래서 어떻게 하면 최적화를 할 수 있을지, 좀 더 깔끔한 코드가 될 수 있을지 고민해봤다.
최적화
최적화를 위해서 willSet에만 넣었다.
둘중의 한곳에만 넣어도 정상적으로 경고메시지가 한번 출력되고 한번 초기화된다.
하지만 나는 willSet에 넣는 것을 선택했다.
이유는 아래와 같다.
- willSet은 새 값이 저장되기 직전에 호출됨.
- didSet은 새 값이 저장된 직후에 호출됨.
그렇다면, "저장되기 전"을 선택했다.
코드를 다시 한번 보자.
var balance: Double = 0.0 {
willSet(newValue) {
if newValue >= 0.0 {
print("\(newValue)원을 입금하겠습니다.")
print("기존 잔액: \(balance), 입금 후 잔액: \(newValue)\n\n")
} else {
print("🚨 경고: 잔액은 음수가 될 수 없습니다. 잔액을 0원으로 설정합니다.")
balance = 0.0
print("최종 잔액: \(balance)원")
}
}
didSet {
if balance >= 0.0 {
print("입금이 완료되었습니다.")
print("현재 잔액: \(balance), 기존 잔액: \(oldValue)\n")
print("최종 잔액: \(balance)원")
}
}
}
balance = -1000
다시한번 말하지만,
willSet은 저장되기 직전
didSet은 저장된 직후 이다.
여기서 음수 -1000을 저장하려고 시도했을때,
willSet의 if문을 한번 보자.
newValue가 0.0보다 작기때문에 if문을 통과하지 못하고 else로 빠져서 경고문을 출력하게 된다.
저장되지 않았기때문에, 초기화하지 않아도 값은 같지만,
좀 더 안정성있게 가기 위해서 balance = 0.0이라는 코드로 다시 0.0으로 초기화를 해주었다.
이렇게 해서 저장되기 전에 걸러줌으로써 나름대로의 최적화를 해보았다.
경고문 출력도 한번, 초기화도 한번.
나름대로의 좀 더 깔끔하고 최적화 된 코드를 작성해보았다.
만약 didSet에 넣으면 어떻게 될까?
코드를 보자.
var balance: Double = 0.0 {
willSet(newValue) {
if newValue >= 0.0 {
print("\(newValue)원을 입금하겠습니다.")
print("기존 잔액: \(balance), 입금 후 잔액: \(newValue)\n\n")
}
}
didSet {
if balance >= 0.0 {
print("입금이 완료되었습니다.")
print("현재 잔액: \(balance), 기존 잔액: \(oldValue)\n")
print("최종 잔액: \(balance)원")
} else {
print("🚨 경고: 잔액은 음수가 될 수 없습니다. 잔액을 0원으로 설정합니다.")
balance = 0.0
print("최종 잔액: \(balance)원")
}
}
}
balance = 1000
willSet은 저장되기 직전에 호출된다.
하지만 if문에서 이미 newValue가 0.0보다 작다는 전제하에 걸러졌기 때문에, print문들이 출력되지 않는다.
현재 위의 코드의 willSet문을 해석하면 일단 그냥 저장하고 didSet으로 넘어가는 것이다.
예시를 보자.
var balance: Double = 0.0 {
willSet(newValue) {
if newValue >= 0.0 {
print("\(newValue)원을 입금하겠습니다.")
print("기존 잔액: \(balance), 입금 후 잔액: \(newValue)\n\n")
}
}
/* didSet {
if balance >= 0.0 {
print("입금이 완료되었습니다.")
print("현재 잔액: \(balance), 기존 잔액: \(oldValue)\n")
print("최종 잔액: \(balance)원")
} else {
print("🚨 경고: 잔액은 음수가 될 수 없습니다. 잔액을 0원으로 설정합니다.")
balance = 0.0
print("최종 잔액: \(balance)원")
}
} */
}
balance = -1000
print("\(balance)")
didSet문을 주석처리하고 실행해보았다.
willSet의 print문의 결과는 당연히 -1000이 그대로 저장되어 -1000이 출력되었다.
if문을 통과하지 못했기 때문에, 값은 저장되었지만, print문들은 출력되지 않은 것이다.
주석처리를 해제하고, 다시 기존 코드로 돌아오자.
var balance: Double = 0.0 {
willSet(newValue) {
if newValue >= 0.0 {
print("\(newValue)원을 입금하겠습니다.")
print("기존 잔액: \(balance), 입금 후 잔액: \(newValue)\n\n")
}
}
didSet {
if balance >= 0.0 {
print("입금이 완료되었습니다.")
print("현재 잔액: \(balance), 기존 잔액: \(oldValue)\n")
print("최종 잔액: \(balance)원")
} else {
print("🚨 경고: 잔액은 음수가 될 수 없습니다. 잔액을 0원으로 설정합니다.")
balance = 0.0
print("최종 잔액: \(balance)원")
}
}
}
balance = -1000
willSet에서 if문을 통과하지 못하고 걸러졌기 때문에, print문들은 출력되지 못했다.
하지만 값은 저장하고 didSet으로 넘어간다.
그리고 didSet에서도 마찬가지로 if문을 통과하지 못했기 때문에, else로 넘어간다.
이제 경고문이 출력되고, 0.0으로 다시 초기화 된다!
최적화를 마치며
willSet에 넣나, didSet에 넣나
출력되는 결과물은 같다.
하지만 willSet을 선택한 이유와 차이점은, 값이 저장되기 전에 경고문을 출력하고 초기화를 하느냐
아니면 일단 저장을 하고 경고문을 출력하고 초기화를 하느냐의 차이다.
지금은 간단한 코드이기에 문제가 없겠지만, 나중에 좀 더 큰 규모의 프로젝트를 하고 코드를 구현해야 할 때,
이런 작은 최적화 하나하나가 모여 에러를 방지하고 앱의 성능을 좌우한다고 생각한다.
앞으로도 어떻게 하면 좀 더 최적화되고 깔끔한 코드를 작성할 수 있을지 고민해봐야겠다.
'개발일지' 카테고리의 다른 글
기초 문법 복습 - String과 Character (0) | 2024.10.09 |
---|---|
운동 관리 시스템을 만들어보자! (function) (2) | 2024.09.30 |
직사각형의 넓이와 둘레를 계산해보자. (0) | 2024.09.26 |
성적 관리 시스템 만들기 (0) | 2024.09.25 |
데이터 다루기 실습 (0) | 2024.09.20 |
살아남는 iOS 개발자가 되기 위해 끊임없이 노력하고 있습니다.