[Swift] 프로퍼티
속성과 메서드
구조체와 클래스에는 속성(프로퍼티)와 메서드가 존재한다
속성은 두 타입에서 동일! 메서드에서는 약간의 차이가 있음
- 저장 속성
    
- 지연 속성
 
 - 계산 속성
 - 타입 속성
    
- 타입 저장 속성
 - 타입 계산 속성
 
 - 속성 감시자 등
 
- 인스턴스 메서드
 - 타입 메서드
 - 서브스크립트
 - 생성자
 - 소멸자
 
1. 저장 속성(Stored Properties)
- 클래스/구조체에서 찍어낸 각 인스턴스가 가지는 고유의 데이터
 - var/let으로 선언가능
 객체 초기화를 마치는 경우, 저장 속성은 반드시 값을 가져아함(기본값 & 생성자 & 옵셔널 타입)- 열거형은 따로 메모리 공간이 필요한 저장 속성은 선언 불가능
 - 저장 속성은 각 속성 자체가 고유의 메모리 공간을 갖는다
 
struct Person {
	//저장 속성!
	var name: String
	var age: Int
	func sit() {
		print("앉는다")
	}
1-1. 지연 저장 속성(Lazy Stored properties)
- 게으른 저장 속성으로 처음부터 값을 초기화하지 않고 지연시킴
 - 해당 속성이 반드시 처음부터 초기화가 필요하지 않은 경우 (이미지 등 메모리 공간을 많이 차지하는 속성에서 주로 사용)
 - 값에 대한 접근이 있어야 메모리 공간을 생성하여 초기화시킨다
 - lazy var로만 선언 가능(lazy let 불가능)
 - 
    
초기화를 지연시키기 때문에 반드시 기본값이 필요(기본값에 함수 실행문, 계산식, 클로저 실행문 들어갈 수 있음)
 - 지연 저장 속성 사용하는 이유?
    
- 메모리 공간 낭비와 불필요한 성능저하를 줄인다 → 메모리 공간을 많이 차지하는 이미지와 같은 속성들 다룰
 - 다른 저장 속성을 이용하여 선언해야 할 경우
 
 
struct Person {
    var name: String
    lazy var age: Int = 20
		//컴파일 에러 
    var nameCount: Int = name.count
		//다른 저장 속성을 이용하여 선언해야 할 경우 lazy 사용
    lazy var nameCount: Int = {
				return name.count
		}()
    init(name: String) {
        self.name = name
    }
}
var p1 = Person(name: "soom")
//해당 변수에 접근하는 시점에서 초기화된다! (메모리 공간 생성)
//접근 이후에는 계속 메모리 공간에 남아있음
var age = p1.age
p1.age = 22
struct View {
	var count: Int
	//해당 속성이 메모리를 많이 차지할 경우 늦게 메모리에 올리기 위해 사용한다
	lazy var view = UIImageView()
	//다른 속성을 이용하여할 때
	lazy var b: Int = {
		return a * 10
	}()
}
2. 계산 속성(Computed Properties)
- 실질적으로 메서드 역할을 하는 속성임
 - 다른 저장 속성에 의존한 결과로 나옴
 인스턴스에 메모리 공간이 할당되지 않음→ 실질적으로 메서드!- var로만 선언 가능 & 자료형까지 선언
 - get 블록 : 해당 인스턴스의 값을 얻는다
    
- 필수구현
 - get 블록만 선언시 읽기 전용 (Read-Only)
 - 읽기 전용의 프로퍼티 선언시 get블록 생략 가능
 
 - set 블록 : 밖에서 해당 인스턴스에 접근하여 값을 세팅한다
    
- 기본 파라미터 newValue가 제공됨 (파라미터 이름 설정도 가능)
 
 
class Person {
    var name: String = "사람"
    var height: Double = 160.0
    var weight: Double = 60.0
    
		//다른 속성의 저장 속상을 계산해서 나오는 방식의 메서드를 계산 속성으로 바꿀 수 있다!
    func calculateBMI() -> Double {
        let bmi = weight / (height * height) * 10000
        return bmi
    }
		
		var bmi: Double {
        get {                                               
            let result = weight / (height * height) * 10000
            return result
        }
    }
		//get 블록 생략 가능
		var bmi: Double {
		      let bmi = weight / (height * height) * 10000
		      return bmi
		  }
		
		var bmi: Double {
		        get {       
		            let bmi = weight / (height * height) * 10000
		            return bmi
		        }
		        set(bmi) {  
		            weight = bmi * height * height / 10000
		        }
		}
}
- 메서드 대신 계산 속성 사용시 장점
    
- 관련이 있는 두가지 메서드(함수)를 한번에 구현할 수 있다
 - 외부에서 보기에 속성이름을 설정가능하므로 보다 명확해보인다
 - 계산 속성은 메서드를 개발자들이 보다 읽기 쉽고, 명확하게 쓸 수 있는 형태인 속성으로 변환해놓은 것이다.
 
 
2-1) 계산 프로퍼티의 메모리 동작 구조 (클래스 기준)
메모리 공간을 가지지 않는다
(항상 메서드의 실행은 스택 프레임에서 실행된다)
- 구조체의 경우 실제로는 함수 메모리 주소 직접 접근
 
3. 계산속성 vs 지연저장속성
지연저장속성은 접근 이후 메모리에 계속 남아있기 때문에 메모리가 큰 프로퍼티 다룰 때 사용한다.
지연저장속성은 한번 접근해서 그 값을 초기화하면 그 값이 계속 유지된다
반면에, 계산속성은 접근 시마다 연산을 하기 때문에 계속 값이 변한다