티스토리 뷰
이전에 프로퍼티에 대해 블로깅을 했었지만
복습겸 공식문서를 보고 한번더 정리해보려고 합니다.
프로퍼티
프로퍼티는 클래스, 구조체, 열거형과 관련한 값입니다.
추가로, 프로퍼티 옵저버를 정의하여 값의 변경사항을 모니터링할 수 있으며, 사용자 지정작업으로 응답할 수 있습니다.
프로퍼티 옵저버는 사용저가 정의한 저장프로퍼티와 하위 클래스가 상위클래스에서 상속받는 프로퍼티에 추가될 수 있습니다. (질문)
종류
- 저장 프로퍼티 (Stored Properties) - 값을 저장하고 있는 프로퍼티 ( 클래스, 구조체 )
- 연산 프로퍼티 (Computed Properties) - 값을 저장하지 않고 계산 값을 반환해주는 프로퍼티 ( 클래스, 구조체, 열거형 )
저장 프로퍼티 (Stored Properties)
값을 저장하고 있는 프로퍼티로,
상수(let), 변수(var)를 선언해 사용할 수 있습니다.
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
// the range represents integer values 0, 1, and 2
rangeOfThreeItems.firstValue = 6
// the range now represents integer values 6, 7, and 8
위 예제는 firstValue와 length에 각각 프로퍼티에 값을 저장해 범위 값을 표현합니다.
상수 구조체 인스턴스의 저장 프로퍼티 (Stored Properties of Constant Structure Instances)
상수로 인스턴스화한 구조체는 해당 인스턴스의 프로퍼티를 수정할 수 없습니다.
( 수정하는 프로퍼티가 변수더라도 수정 불가 )
//struct FixedLengthRange {
// var firstValue: Int
// let length: Int
//}
let rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3) // let으로 변경
// the range represents integer values 0, 1, and 2
rangeOfThreeItems.firstValue = 6 // 에러
// this will report an error, even though firstValue is a variable property
이유는 struct가 값 타입이기 때문입니다.
값 타입의 인스턴스가 상수로 선언되면, 모든 프로퍼티의 경우 수정할 수 없게 됩니다.
반대로, class의 경우 참조 타입이기 때문에 프로퍼티 값을 변경할 수 있습니다.
지연 저장 프로퍼티 (Lazy Stored Properties)
값이 처음 사용되기까지 계산되지 않는 프로퍼티 입니다.
지연 저장 프로퍼티는 lazy 키워드를 사용하여 나타낼 수 있습니다.
NOTE
lazy 프로퍼티는 항상 var 키워드와 함께 써야합니다.
상수는 (let) 초기화 되기전에 항상 값을 갖고 있어야 하므로, lazy와 함께 쓰이면 안됩니다.
유용하게 사용될 때
- 외부요인에 의존적이어서 인스턴스의 초기화 완료까지 값을 알지 못하는 경우.
- 복잡한 계산이나 부하가 많이 걸리는 작업일 경우.
아래 예제는 lazy 저장 프로퍼티를 써서 복잡한 클래스의 불필요한 초기화를 피하도록 하기 위해 사용되었습니다.
class DataImporter {
// DataImporter는 외부파일에서 데이터를 가지고 오는 클래스
// 이 클래스는 초기화 하는데 많은 시간이 걸리고, 데이터를 가져오는 기능을 한다고 가정
var filename = "data.txt"
}
class DataManager {
lazy var importer = DataImporter()
var data = [String]()
// 이 클래스는 데이터관리 기능이 있다고 가정
}
let manager = DataManager()
manager.data.append("data1")
manager.data.append("data2")
// DataImporter 인스턴스는 이 시점에 생성되어 있지 않습니다. (lazy 프로퍼티 때문)
위의 코드를 풀이 해보자면
DataManager 클래스에 DataImporter라는 클래스를 인스턴스화 해서 갖고 있습니다.
DataImporter는 데이터파일을 가져와 많은 시간이 걸리기 때문에,
lazy var importer = DataImporter()
lazy 프로퍼티로 선언을 해줌으로써 DataManager가 호출되어도 importer가 불려지지 않는이상 실행 되지 않습니다.
아래와 같이 manger.importer로 직접 접근하면 그제서야 importer 인스턴스가 생성됩니다.
print(manager.importer.filename) // importer 호출
// DataImporter 인스턴스 생성
// print: data.txt
NOTE
lazy 프로퍼티가 여러 스레드에서 접근되고, 프로퍼티가 아직 초기화 되지 않았을때
프로퍼티가 한번만 초기화 될거라는건 보장할수 없습니다. (질문)
저장 프로퍼티와 인스턴스 변수 (Stored Properties and Instance Variables)
Objective-C의 경우 값을 저장하는방법과 메모리 관리 개념도 프로퍼티에 함께 명시한다고 하는데
Swift에서는 프로퍼티의 선언과 사용에 혼란을 피하기위해
프로퍼티의 이름, 타입, 메모리 관리등 모든 정보를 프로퍼티 선언하는 곳에서 정의하게 됩니다.
연산 프로퍼티 (Computed Properties)
저장프로퍼티 뿐만 아니라 클래스, 구조체, 열거형에서 연산프로퍼티를 선언할 수 있습니다.
연산프로퍼티는 실제로 값을 저장하지 않는 대신, 다른 프로퍼티와 값을 간접적으로 탐색하고 설정하기 위해 getter와 옵셔널한 setter를 제공합니다.
아래는 width: 10, height: 10인 사각형(square) 가운데(center)의 좌표를 (x: 0, y: 0) -> (x: 15, y: 15) 이동 시키는 예제 입니다.
그림으로 먼저 보면
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, height = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
var center: Point {
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
set(newCenter) {
origin.x = newCenter.x - (size.width / 2)
origin.y = newCenter.y - (size.height / 2)
}
}
}
// 1
var square = Rect(origin: Point(x: 0.0, y: 0.0),
size: Size(width: 10.0, height: 10.0))
// 2
let initialSquareCenter = square.center
// initialSquareCenter is at (5.0, 5.0)
// 3
square.center = Point(x: 15.0, y: 15.0)
코드 풀이
위 예제에 세가지 구조체 (Point, Size, Rect)가 있습니다.
- Point 는 좌표 (x, y)
- Size 는 크기 (width, height)
- Rect 는
- origin (좌표)
- size (크기)
- center (가운데) 연산 프로퍼티가 있습니다.
1. 변수 square 선언 - Point 값 (x: 0.0, y: 0.0), Size 값 (width: 10.0, height: 10.0)
2. initialSquareCenter = square.center 부분을 보면
centerX = origin.x(0) + (size.width(10.0) / 2)
centerY = origin.y(0) + (size.height(10.0) / 2)
return Point(x: 5.0, y: 5.0) 가 됩니다.
3. square.center = Point(x: 15.0, y: 15.0) x, y 값을 바꿔줬네요.
center의 값을 바꿔준거니 set으로 이동해서 newCenter는 아래처럼 연산됩니다.
origin.x = newCenter.x (15) - (size.width(10) / 2)
origin.y = newCenter.y (15) - (size.height(10) / 2)
고로 square의 현재 좌표는 (x: 10, y: 10) 크기는 (width: 10, height: 10)이 됩니다.
간략한 Setter 선언 (Shorthand Setter Declaration)
위 예제에서 setter 부분에 (newCenter)로 이름을 지정해주지 않으면,
newValue라는 기본값으로 사용할 수 있습니다.
아래는 set (newCenter) 를 사용하지 않은 예제 입니다.
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, height = 0.0
}
struct AlternativeRect {
var origin = Point()
var size = Size()
var center: Point {
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
set {
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
}
읽기전용 연산 프로퍼티 (Read-Only Computed Properties)
getter만 있는 연산 프로퍼티는 읽기 전용 연산 프로퍼티로 알려져 있습니다.
읽기 전용 연산 프로퍼티는 항상 값을 반환하며, .(점 문법)으로 접근할 수 있지만, 다른 값을 지정할 수는 없습니다.
NOTE
읽기전용 연산 프로퍼티를 포함한 연산프로퍼티들은 값이 고정되어 있지 않기 때문에 var키워드로 선언해야 합니다.
(계산 값에 따라 값이 변할수 있기 때문에)
아래는 읽기전용 연산 프로퍼티를 사용한 예제 입니다.
struct Cuboid {
var width = 0.0, height = 0.0, depth = 0.0
var volume: Double {
return width * height * depth
}
}
let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
print("the volume of. ourByFiveBy Two is \(fourByFiveByTwo.volume)")
// the volume of. ourByFiveBy Two is 40.0
width, heigth, depth 를 가지고 연산을 하기 때문에 값이 항상 바뀌므로 var 키워드 사용
다음 블로깅에서는
프로퍼티 옵저버
타입 프로퍼티
에 대해 블로깅 해보겠습니다.
'iOS' 카테고리의 다른 글
[Swift] 프로퍼티 (Properties) - Observers, Type properties (2/3) (0) | 2022.03.06 |
---|---|
[Swift] 프로퍼티 - Property Wrapper (3/3) (0) | 2022.03.04 |
[iOS] 빈화면 터치시 TextField 키보드 내리기 (0) | 2022.02.27 |
[iOS] 생명주기 메소드 AppDelegate & SceneDelegate (Lifecycle method) (0) | 2022.02.25 |
[iOS] 로컬 푸시 알림 (Local push notification) (0) | 2022.02.19 |
- Total
- Today
- Yesterday
- 2023년 회고
- iOS error
- Swift joined
- Class
- RTCCameraVideoCapturer
- swift property
- Swift Error Handling
- Swift init
- Combine: Asynchronous Programming with Swift
- Swift 프로퍼티
- swift 고차함수
- Swift 알고리즘
- Swift RIBs
- Swift inout
- 원티드 프리온보딩
- Swift final
- removeLast()
- Swift Leetcode
- CS 네트워크
- swift programmers
- RIBs tutorial
- Swift 내림차순
- Swift ModernRIBs
- swift protocol
- ios
- swift reduce
- Swift 프로그래머스
- swift (programmers)
- Swift
- Swift joined()
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |