조앤의 기술블로그

[Swift] Property(프로퍼티) #1 본문

Study/Swift

[Swift] Property(프로퍼티) #1

쬬앤 2020. 2. 20. 15:34

저장 속성(Stored Property), 계산 속성(Computed Property)에 대해 알아보겠습니다.

<Stored Property (저장속성)>

저장 속성은 인스턴스에 속한 속성으로, 클래스와 구조체에서 선언 가능합니다. 

즉, 인스턴스가 생성될 때마다 새로운 메모리에 저장됩니다. 

// Variable Stored Property
var name: Type = DefaultValue

// Constant Stored Property
let name: Type = DefaultValue

초기값을 지정할 경우 형식추론을 할 수 있으므로 자료형을 생략할 수 있습니다. 

초기값을 지정하지 않을 경우엔, 자료형을 지정해주어야 합니다. 

 

상수 저장 속성은 초기화 이후에 값을 변경할 수 없습니다. 

class Member {
	let name: String = "Jin"
    var age: Int = 29
}

name 과 age 가 저장속성입니다. 

 

[Explicit Member Expression]

저장 속성에 접근할 때는 점문법(Explicit Member Expression)으로 접근할 수 있습니다. 

 

let m = Member()
m.name
m.age

m.age = 30
// m.name = "New Name" // error

인스턴스를 생성하고, 점문법으로 속성에 접근하여 값을 변경할 수도 있습니다. 

하지만 name은 let으로 선언된 '상수'이기 때문에 값을 변경할 수 없습니다. 

 

Member Class를 Struct로 변경해보겠습니다. 

struct Member {
	let name: String = "Jin"
    var age: Int = 29
}

let m = Member()
m.age
m.name
// m.age = 30 //error

이 코드에서는 m.age = 30 에서 에러가 납니다. age는 var 키워드로 선언되어있는데, 왜그럴까요?

인스턴스 m이 let으로 선언되었기 때문입니다. 

 

구조체 인스턴스가 상수로 선언되면 속해있는 모든 속성이 상수로 변하기 때문에 값을 변경할 수 없게 됩니다. 

즉, 구조체의 가변성은 속성의 가변성에 영향을 미칩니다. 

따라서 m.age = 30 에서 에러가 나지 않도록 하려면 var m = Member()로 코드를 변경해주어야 합니다. 

 

[Lazy Stored Properties]

lazy stored properties는 저장 속성의 초기화 시점을 지연시킵니다. 

 

일반 저장 속성은 인스턴스가 초기화될 때(Initialization) 저장 속성이 초기화되지만, 

lazy 저장 속성은 인스턴스에 처음 접근할 때(First Access) 저장 속성이 초기화됩니다. 

 

lazy var name: Type = DefaultValue

인스턴스가 초기화 된 이후에 개별적으로 초기화되기 때문에 항상 '변수 저장 속성'입니다. 

즉, 항상 var 키워드로 선언해야 합니다. 

 

또, 생성자에서 초기화하지 않기 때문에 선언 시점에 기본 값을 저장해야 합니다. 

 

[예제]

struct Image {
	init() {
    	print("new image")
    }
}

struct BlogPost {
	let title: String = "Title"
    let contents: String = "Content"
    lazy var attatchment: Image = Image()
}
var post = BlogPost()

 

<Computed Property (계산속성)>

계산 속성의 'Computed'의 의미는 다른 속성을 기반으로 값을 결정(계산한다.)는 뜻입니다. 

저장 속성과 달리 메모리 값을 가지지 않습니다. 

 

클래스, 구조체, 열거형에서 사용할 수 있습니다. 

var name: Type {
	get {
    	statements
        return expr
    }
    set(name) {
    	statements
    }
}

기본값을 지정하지 않기 때문에 형식 추론이 불가능합니다. 따라서 타입을 지정해 주어야 합니다. 

그리고 인스턴스마다 계산 속성의 값이 달라질 수 있기 때문에 var 키워드로 선언해야 합니다. 

get block에서는 표현식을 return 해주어야 합니다. 

set 블록의 파라미터 name은 생략할 수 있고, 그럴 경우 기본 파라미터(newValue)가 제공됩니다. 

 

class Person {
	var name: String
    var yearOfBirth: Int
    
    init(name: String, year: Int) {
    	self.name = name
        self.yearOfBirth = year
    }
    
    var age: Int {
    	get {
        	let calendar = Calendar.current
            let now = Date()
            let year = Calendar.component(.year, from: now)
            return year - yearOfBirth
        }
        set {
        	let calendat=r = Calendar.current
            let now = Date()
            let year = Calendar.component(.year, from: now)
            yearOfBirth = year - newValue
        }
    }
}

여기서 age 가 계산 속성입니다. 

yearOfBirth와 현재 날짜인 Date로 age를 계산하여 속성으로 저장할 수 있기 때문입니다. 

set에서 기본 파라미터로 newValue가 사용되었습니다. 

 

let p = Person(name: "SeokJin", year: 2013)
p.age

p.age = 29
p.yearOfBirth

 

[Read-Only Computed Properties]

set block을 삭제하면 읽기 전용 계산 속성이 됩니다. (쓰기 전용 계산 속성은 없습니다.)

var name: Type {
	get {
    	statements
        return expr
    }
}

주로 get { }을 삭제한 아래의 모습으로 많이 사용됩니다. 

age: Int {

}

처럼 할당 연산자가 없으면 읽기전용 계산속성입니다. 

var name: Type {
	statements
    return expr
}

 

 

 

 

 

참고, 코드 인용 : KxCoding.com - Hello, Swift 강의 

'Study > Swift' 카테고리의 다른 글

[Swift] Method and Subscript  (0) 2020.02.21
[Swift] Property(프로퍼티) #2  (0) 2020.02.20
Tuples (튜플)  (0) 2020.02.18
[Swift] Functions #2  (0) 2020.02.18
Functions #1 (function, return type, parameter)  (0) 2020.02.18