프로퍼티
저장 프로퍼티(Stored Properties)
- 가장 기본 형식으로 클래스 또는 구조체 인스턴스의 뿐으로 저장된 상수 또는 변수
struct FixedLengthRange {
//저장 프로퍼티
var firstValue: Int
let length: Int
}
// 상수로 생성된 구조체 인스턴스는 프로퍼티가 변수여도 수정이 불가능
// 클래스 인스턴스는 상수로 생성돼도 수정 가능
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
rangeOfFourItems.firstValue = 6 //error
지연 저장 프로퍼티(Lazy Stored Properties)
- 처음 사용될 때까지 초기값이 계산되지 않는 프로퍼티
- 지연 저장된 프로퍼티는 선언 전에
lazy
수정자를 붙여 나타낸다.프로퍼티 상수는 초기화가 완료되기 전에 항상 값을 가지고 있어야 하므로 lazy로 선언할 수 없다
- 인스턴스의 초기화가 완료될 때까지 값을 알 수 없는 외부 요인에 인해 초기값이 달라질 때 유용
- 초기값으로 필요할 때까지 수행하면 안되는 복잡하거나 계산 비용이 많이 드는 경우에도 유용
class DataImporter {
var filename = "data.txt"
}
class DataManager {
lazy var importer = DataImporter()
var data = [String]()
}
let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
print(manager.importer.filename)
- 파일로 부터 데이터를 가져올 필요 없이 데이터를 관리할 수 있으므로
DataManager
인스턴스가ataImporter
인스턴스를 처음 사용하는 경우에 생성하는 것이 더 합리적
연산 프로퍼티(Computed Properties)
- 값을 실질적으로 저장하지 않음
- 대신 다른 프로퍼티와 값을 간접적으로 조회하고 설정하는 getter와 옵셔널 setter를 제공
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)
}
}
}
var square = Rect(origin: Point(x: 0.0, y: 0.0),
size: Size(width: 10.0, height: 10.0))
//사각형 센터를 연산 프로퍼티를 통해 get
let initialSquareCenter = square.center // (5.0, 5.0)
//사각형 센터를 연산 프로퍼티를 통해 set
square.center = Point(x: 15.0, y: 15.0) // (10.0 , 10.0)
setter
가 새로운 값을 설정하는데 이름을 정의하지 않았다면newValue
라는 기본 이름이 사용 ex) 위코드에서newCenter
를 설정해주지 않았다면newValue
이름으로 자동적으로 설정getter
의 전체 바디가 단일 표현식이라면getter
는 암시적으로 표현식을 반환
읽기전용 연산 프로퍼티 (Read-Only Computed Properties)
getter
만 있는 연산 프로퍼티- 읽기전용 연산 프로퍼티는 항상 값을 반환하고 점 구문으로 접근할 수 있지만 다른 값을 설정할 수 없다!
get
키워드와 그것의 중괄호를 삭제하고 읽기전용 계산된 프로퍼티를 간편하게 선언할 수 있다
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)
fourByFiveByTwo.volume // 40
프로퍼티 관찰자(Property Observers)
- 프로퍼티의 값이 변경되는지 관찰하고 응답
- 프로퍼티의 현재 값이 새로운 값과 같더라도 프로퍼티의 값이 설정될 때 호출
- 프로퍼티에 관찰자를 정의하는 방법은 2가지 선택사항을 가지며 둘다 정의할 수도 있다
willSet
은 값이 저장되기 직전에 호출
didSet
은 새로운 값이 저장되자마자 호출
willSet
willSet
구현의 일부로 이 파라미터에 특정 이름을 가질 수 있다willSet
관찰자는 상수 파라미터로 새로운 프로퍼티 값이 전달- 파라미터 명과 구현 내에 소괄호를 작성하지 않으면 파라미터는 newValue 의 기본 파라미터 명으로 만들어 짐
didSet
didSet
관찰자는 예전 프로퍼티 값을 포함한 상수 파라미터가 전달- 파라미터 명을 사용하거나
oldValue
인 기본 파라미터 명을 사용. didSet
관찰자 내의 프로퍼티에 값을 할당한다면 새로운 값으로 방금 설정한 값을 대체
예시
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
print("About to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
print("Added \(totalSteps - oldValue) steps")
}
}
}
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps
프로퍼티 래퍼(Property Wrappers)
- 프로퍼티가 저장되는 방법을 관리하는 코드와 프로퍼티를 정의하는 코드 사이에 분리 계층을 추가
TwelveOrLess
구조체는 래핑하는 값이 항상 12와 같거나 더 작은 숫자가 됌. 더 큰 숫자를 저장하도록 하면 12가 저장
@propertyWrapper
struct TwelveOrLess {
private var number = 0
var wrappedValue: Int {
get { return number }
set { number = min(newValue, 12) }
}
}
속성으로 프로퍼티 전에 래퍼의 이름을 작성하여 프로퍼티에 래퍼를 적용.
다음은 항상 12 이하인지 확인하기 위해 TwelveOrLess
프로퍼티 래퍼를 사용하여 사각형을 저장하는 구조체
struct SmallRectangle {
@TwelveOrLess var height: Int
@TwelveOrLess var width: Int
}
var rectangle = SmallRectangle()
print(rectangle.height)
// Prints "0"
rectangle.height = 10
print(rectangle.height)
// Prints "10"
rectangle.height = 24
print(rectangle.height)
// Prints "12"
@TwelveOrLess
를 작성하는 대신에 TwelveOrLess
구조체에 명시적으로 프로퍼티를 래핑
struct SmallRectangle {
private var _height = TwelveOrLess()
private var _width = TwelveOrLess()
var height: Int {
get { return _height.wrappedValue }
set { _height.wrappedValue = newValue }
}
var width: Int {
get { return _width.wrappedValue }
set { _width.wrappedValue = newValue }
}
}
타입 프로퍼티(Type Properties)
- 타입 자체에 속하는 프로퍼티
- 모든 인스턴스에서 사용할 수 있는 프로퍼티 상수 or 모든 인스턴스에 전역인 값을 저장하는 프로퍼티 변수와 같은 특정 타입에 모든 인스턴스에 보편적인 값을 정의하는데 유용
- 저장 타입 프로퍼티에는 기본값이 항상 존재해야함
- 초기화 시 저장된 타입 프로퍼티에 값을 할당할 수 있는 초기화를 가지고 있지 않기 때문
static
키워드로 타입 프로퍼티를 정의- 클래스 타입의 연산 타입 프로퍼티의 경우
class
키워드를 대신 사용하여 하위 클래스에서 상위 클래스의 구현을 재정의 가능
struct SomeStructure {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 1
}
}
enum SomeEnumeration {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 6
}
}
class SomeClass {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 27
}
class var overrideableComputedTypeProperty: Int {
return 107
}
}
Author And Source
이 문제에 관하여(프로퍼티), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@strangeman/프로퍼티저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)