Notice
Recent Posts
Recent Comments
Link
大器晩成
타입속성 (Type Properties) 본문
- 클래스나 구조체, 또는 열거형과 같은 객체 자체에 관련된 값을 다루어야 할 때도 있는데, 이때는 인스턴스를 생성하지 않고 클래스나 구조체 자체에 값을 저장하게 되며 이를 타입 프로퍼티(Type Property)라고 부릅니다.
- 타입 프로퍼티는 클래스나 구조체의 인스턴스에 속하는 값이 아니라 클래스나 구조체 자체에 속하는 값이므로 인스턴스를 생성하지 않고 클래스나 구조체 자체에 저장되며, 저장된 값은 모든 인스턴스가 공통으로 사용할 수 있습니다.
- 인스턴스 프로퍼티는 개별 인스턴스마다 다른 값을 저장할 수 있어서 하나의 인스턴스에서 변경한 프로퍼티의 값은 그 인스턴스 내에서만 유지될 뿐 나머지 인스턴스에 영향을 미치지 많지만, 타입프로퍼티는 인스턴스가 아무리 많더라도 모든 인스턴스가 하나의 값을 공용으로 사용한다.
// 클래스 내부에서
static let/var 프로퍼티명 = 초기값
또는
class let/var 프로퍼티명: 타입 {
get {
return 반환값
}
set {
}
}
- 타입 프로퍼티를 정의하는 또 다른 키워드인 class는 클래스에서 연산 프로퍼티에만 붙일 수 있는 키워드입니다.
- 구조체이거나 저장 프로퍼티일 경우에는 사용할 수 없습니다. 이 키워드를 사용하여 타입 프로퍼티를 선언하면 상속받은 하위 클래스에서 재정의 할 수 있는 타입 프로퍼티가 됩니다.
- 변수나 상수 어느 것이든 타입 프로퍼티를 사용할 수 있지만, 이를 이용하여 정의한 저장 프로퍼티를 타입 프로퍼티로 선언할 때에는 초기값을 반드시 할당해야 합니다.
- 타입 프로퍼티는 인스턴스와 상관없기 때문에 인스턴스 생성과정에서 초기값을 할당할 수 없습니다.
- 인스턴스에 속한 속성이 아니고, 타입자체에 속한 속성이기에 내/외부에서 Type.property로 접근해야 합니다
- 저장 타입 속성을 주로 사용합니다.
struct Foo {
//타입 저장 프로퍼티
static var sFoo = "구조체 타입 프로퍼티 값"
//타입 연산 프로퍼티
static var cFoo: Int {
return 1
}
}
//이렇게 선언되 낱입 프로퍼티들은 별도의 인스턴스 생성 없이 사용 가능
//클래스나 구조체 자체에 점 구문을 이용하여 타입 프로퍼티 참조
print(Foo.sFoo) // 구조체 타입 프로퍼티 값
Foo.sFoo = "새로운 값"
print(Foo.sFoo) // 새로운 값
class Boo {
//타입 저장 프로퍼티
static var sboo = "클래스 타입 프로퍼티 값"
//타입 연산 프로퍼티
static var cBoo: Int {
return 10
}
// 재정의 가능한 타입 연상 프로퍼티
class var oCoo: Int {
return 100
}
}
print(Boo.sboo) // 클래스타입 프로퍼티 값
Boo.sboo = "새로운 값"
print(Boo.sboo) // 새로운 값
// 타입 프로퍼티는 인스턴스에 속하지 않는 값이므로 만약 인스턴스를 생성한 다음 점 구문을 이용하여
// 타입 프로퍼티를 읽으려고 하면 선언되지 않은 프로퍼티라는 오류 발생
//let a = Foo()
//a.sFoo // => 인스턴스에서 .(점)을 찍어도 속성으로 보이지 않는다.
Boo.sboo // ==> 반드시 타입(형식)의 이름으로 접근해야 함
- 이 값은 복사된 것이 아니라 실제로 하나의 값이므로 하나의 인스턴스에서 타입 프로퍼티의 값을 변경하면 나머지 인스턴스들이 일괄적으로 변경된 값을 적용받습니다.
- 이런 특성 때문에 타입 프로퍼티는 특정 클래스나 구조체, 그리고 열거형에서 모든 인스턴스들이 공유해야 하는 값을 정의할 때 유용합니다.
저장 타입(형식) 속성
class Circle {
//(저장) 타입 속성 (값이 항상 있어야 함)
static let pi = 3.14
static var count = 0 // 인스턴스를 (전체적으로) 몇개를 찍어내는지 확인
//저장 속성
var radius: Double // 반지름
//계산 속성
var diameter: Double {
get {
return radius * 2
}
set {
radius = newValue / 2
}
}
//생성자
init(radius: Double) {
self.radius = radius
Circle.count += 1
}
}
var circle1 = Circle(radius: 5) // 인스턴스를 +1개 찍어냈다. (count == 1)
var circle2 = Circle(radius: 10) // 인스턴스를 +1개 찍어냈다. (count == 2)
let a = Circle.pi
// 실제 사용 예시)
Int.max
Int.min
Double.pi
저장 타입 속성 정리
- 클래스나 구조체 또는 열거형에서 정의할 시 static 키워드를 사용합니다.
- 일반 저장속성은 인스턴스를 생성할 때, 생성자에서 모든 속성에 대한 초기화를 완료하지만, 저장 타입 속성은 클래스나 구조체 자체에서 값을 선언합니다.
- 저장 타입 속성의 경우 let이나 var 둘 다 가능합니다.
- 저장 타입(형식) 속성은 생성자가 따로 없기 때문에, 타입 자체(유형 그 자체)에 속한 속성이기 때문에 항상 기본값(초기값)이 필요하며. 생략 불가능 불가능합니다.
- 타입 저장 속성은 기본적으로 타입 저장 속성에 접근 시 초기화되기 때문에, 지연 속성의 성격을 가집니다.
- 저장 타입속성은 기본적으로 지연 속성 (속성에 처음 접근하는 순간에 초기화됨)이지만, lazy라고 선언할 필요는 없습니다
(참고: 여러 스레드에서 동시에 액세스 하는 경우에도 한 번만 초기화되도록 보장됨. Thread-Safe)
저장 타입속성을 선언하는 경우
- 모든 인스턴스가 동일하게 가져야 하는 속성일 때
- 모든 인스턴스가 공유해야 하는 성격에 가까울 때
계산 타입(형식) 속성
class Circle {
//(저장) 타입 속성 (값이 항상 있어야 함)
static var radius = 3.0
//계산 타입 속성 (Read-Only)
static var diameter: Double {
return radius * 2
}
}
Circle.diameter
- 상속이 있는 경우, 계산 타입 속성에서는 static대신 class 키워드를 사용합니다.
- static(의미: 고정적인) 또는 class 키워드 사용(static 상속 시 재정의 불가/class 상속 시 재정의 가능 의미임)
- var 키워드만 사용 가능(계산 타입 속성) -> 계산속성도 var만 사용 가능
- 메서드이기 때문에 타입에 메모리 공간이 할당되어 있지 않음(계산 속성)
인스턴스 내에서도 접근 가능
class Circle {
// 저장 타입 속성
static let pi: Double = 3.14
// 저장 속성
var radius: Double
// 생성자
init(radius: Double) {
self.radius = radius
}
// 넓이 구하기 ==> 원의 넓이 공식 ==> 파이 X 반지금 제곱
func getArea() -> Double {
// 타입이름으로 접근해야함
let area = Circle.pi * radius * radius // 내부 인스턴스에서도 타입 속성에 접근할때 주의
return area
}
}
let c1 = Circle(radius: 3)
c1.getArea()
- 인스턴스 내에서도 접근하려면 타입이름 + 속성으로 써야 접근 가능합니다.
728x90
'iOS > Swift 문법' 카테고리의 다른 글
인스턴스 메서드 (0) | 2024.11.25 |
---|---|
속성감시자(프로퍼티 옵저버, Property Observer) (0) | 2024.11.25 |
계산/연산 속성(Computed property) (0) | 2024.11.22 |
지연 저장 속성 (Lazy Stored Properties) (0) | 2024.11.21 |
저장속성(Stored Properties) (0) | 2024.11.21 |