일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- FSCalendar
- Swift
- enum
- LeetCode
- viewcontroller
- SwiftUI
- 프로그래머스
- optional
- http
- 알고리즘
- 개발후기
- swipe
- ios13
- API
- typecasting
- flatMap
- SF 폰트
- Xcode
- Lifecycle
- struct
- Crashlytics
- 폰트
- 회고록
- dfs
- ios
- Realm
- TMDB
- RxSwift
- Firebase
- switch
- Today
- Total
Jerry's Bakery
[iOS] Stored Property(저장 프로퍼티) 본문
안녕하세요 Jerry입니다.
Swift의 Stored Property(저장 프로퍼티)에 대해 알아보겠습니다.
iOS를 공부하면서 정리하는 것이기 때문에 미흡한 점이 있을 수 있습니다. 부족한 점에 대해 댓글 남겨주시면 감사하겠습니다.
이 글은 아래 글을 기반으로 만들어졌습니다.
저장 프로퍼티(Stored Properties)
저장 프로퍼티는 가장 간단한 형태로, 특정 클래스와 구조체에서만 사용 가능하며, 인스턴스의 일부로 저장된 상수 또는 변수입니다.
프로퍼티의 속성은 let과 var 둘 다 사용 가능하며, 구조체 인스턴스를 선언하기 전 기본값을 적어줄 수도 있습니다.
아래 예는 Person 구조체에서 두가지 저장 프로퍼티를 선언한 예입니다.
struct Person {
let birthday: Date
var age: Int
}
상수(let) 구조체와 클래스 인스턴스의 저장 프로퍼티 비교
구조체 인스턴스를 상수로 선언했을때와 클래스 인스턴스를 상수로 선언했을 때 안의 값을 비교할 수 있는지에 대해 알아보겠습니다.
우선 Person 구조체 인스턴스를 onePerson 상수에 할당합니다. 그 후 Person구조체의 변수 저장 프로퍼티인 age를 10으로 수정하면 아래와 같이 오류가 발생하는 것을 확인할 수 있습니다.
struct Person {
let birthday: Date
var age: Int
}
// Person 구조체 상수 인스턴스 선언
let onePerson = Person(birthday: Date(), age: 1)
// Person 구조체 상수의 변수 저장 프로퍼티 변경
onePerson.age = 2 // 오류발생!
이번에는 Person 구조체를 클래스로 변경 후 상수 인스턴스로 할당한 후 인스턴스의 멤버 변수를 변경하면 오류가 발생하지 않고 제대로 실행되는 것을 알 수 있습니다.
class Person {
let birthday: Date
var age: Int
init(birthday: Date, age: Int) {
self.birthday = birthday
self.age = age
}
}
// Person 클래스 상수 인스턴스 선언
let onePerson = Person(birthday: Date(), age: 1)
// Person 클래스 상수의 변수 저장 프로퍼티 변경
onePerson.age = 2 // 수행됨
왜 그럴까요?
구조체와 클래스의 저장위치가 다르기 때문입니다.
구조체는 메모리 공간에 값 타입으로 저장하고, 클래스는 메모리 공간에 값의 주소를 저장합니다.
이해하기 쉽게 그림으로 그려보겠습니다.
구조체 변수를 선언한 경우 메모리공간에 구조체 인스턴스가 직접 할당됩니다. 구조체 상수를 선언하고 Person구조체의 저장 프로퍼티를 변경하기 위해서는 구조체 상수 메모리 공간이 변경되야하기 때문에 오류가 발생했던 것입니다. 따라서 오류가 발생하지 않으려면 상수를 변수로 변경해야 합니다.
하지만 클래스 변수를 선언한 경우 클래스 변수에는 실제 클래스 인스턴스가 할당된 위치의 주소를 가지고 있습니다. 클래스 상수를 선언하고, Person 클래스의 저장 프로퍼티를 변경하더라도 인스턴스가 담겨있는 주소 값은 변하지 않기 때문에 오류가 발생하지 않는 것입니다.
구조체는 "값 타입"이고, 클래스는 "참조 타입"입니다.
구조체와 클래스의 차이점에 대해 자세히 알고싶다면 아래 블로그를 방문해주시면 감사하겠습니다.
지연(Lazy) 저장 프로퍼티
지연 저장 프로퍼티는 생성되기 전까지 초기값이 계산되지 않는 것입니다.
지연 프로퍼티는 인스턴스가 초기화되기 전까지 초기값이 검색되지 않을 수 있으므로 지연 프로퍼티를 항상 변수(var)로 선언해야 합니다. 상수 프로퍼티의 경우 인스턴스가 초기화되기 전에 항상 값이 있어야 하기 때문에 상수로 선언할 수 없습니다.
예를 들어 설명해 보겠습니다.
배우자의 여부를 알 수 있는 Partner 클래스를 추가로 선언해 보겠습니다. 만약 아직 결혼을 하지 않았다면 필요 없는 정보이기 때문에 Person 클래스에서 지연 저장 프로퍼티로 선언하였습니다. 아래 코드를 실행했을 때 지연 저장 프로퍼티인 partner를 불렀을 때 partner 프로퍼티가 생성된 것을 확인할 수 있습니다.
class Partner {
let name = "배우자"
}
class Person {
lazy var partner = Partner()
let birthday: Date
var age: Int
init(birthday: Date, age: Int) {
self.birthday = birthday
self.age = age
}
}
// 아직 partner 프로퍼티 생성 안됨
let onePerson = Person(birthday: Date(), age: 1)
// Person 클래스 상수의 변수 저장 프로퍼티 변경
onePerson.age = 2 // 수행됨
// 이제 partner 프로퍼티 생성됨
onePerson.partner.name
지연 저장 프로퍼티는 인스턴스의 결과가 외부의 요인에 의해서 결정될 때 사용하면 유용합니다.
하지만, 지연저장 프로퍼티는 멀티 스레드 환경에서 동시에 접근할 때 아직 프로퍼티가 생성되지 않았다면 프로퍼티가 한 번만 생성함을 보장하지 않기 때문에 유의하여 개발하여야 합니다.
'개발 > iOS' 카테고리의 다른 글
[iOS] SwiftUI 최소버전 iOS 13으로 설정 (0) | 2022.05.26 |
---|---|
[iOS] Xcode 앱 지원 언어 한국어로 바꾸기 (0) | 2021.12.08 |
[iOS/Swift] FSCalendar Swipe(스와이프)로 크기조절하는 방법(애니메이션 효과 적용) (0) | 2021.11.21 |
[iOS] iOS Realm Migration(마이그레이션) 하는법 (0) | 2021.11.04 |
[iOS] 폰트 적용하는 법 (0) | 2021.11.01 |