iOS/Swift

프로퍼티 1편 (저장 프로퍼티)

밤새는 탐험가89 2024. 1. 19. 16:55

 

프로퍼티

클래스, 구조체 또는 열거형에 관련된 값이라는 의미

 

 

프로퍼티의 종류

"저장 프로퍼티"

인스턴스의 변수 또는 상수 의미 

 

"연산 프로퍼티"

값을 저장하는 것이 아닌

특정 연산을 실행한 결과값을 의미

클래스, 구조체, 열거형에서 쓰임

 

"타입 프로퍼티"

저장 프로퍼티, 연산 프로퍼티는 특정 타입의 인스턴스에 사용되지만, 

타입 프로퍼티는 특정 타입에 사용

 

"프로퍼티 감시자"

프로퍼티의 값이 변할 때 값의 변화에 따른 특정 작업 실행 

 

 

 

저장 프로퍼티 

클래스 또는 구조체의 인스턴스와 연관된 값을 저장

(var -> 변수 / let -> 상수)

 

▶ 구조체와 클래스의 저장 프로퍼티 

구조체

저장 프로퍼티가 옵셔널이 아니더라도,

저장 프로퍼티를 포함하는 이니셜라이저를 자동 생성

 

클래스

저장 프로퍼티가 옵셔널이 아니면,

프로퍼티의 기본값 지정 또는 사용자 정의 이니셜라이저를 통해 초기화

 

 

저장 프로퍼티의 선언 및 인스턴스 생성

// 과일 정보
struct Fruit {
    
    // 저장 프로퍼티 
    var name: String 
    var price: Int
}

 

 

구조체에는 기본적으로 저장 프로퍼티를 매개변수로 갖는 이니셜라이저 존재 

 

let appleInfo: Fruit = Fruit(name: "delmont appple", price: 5000)
print("name: \(appleInfo.name), price: \(appleInfo.price) won")
// name: delmont appple, price: 5000 won

 

 

// 가게 정보
class Market {
    var name: String
    var product: Fruit
    
    init(name: String, product: Fruit) {
        self.name = name
        self.product = product
    }
}

 

 

 

클래스 인스턴스의 저장 프로퍼티에 초기값을 지정하지 않으면

사용자 정의 이니셜라이저를 구현해야함 

let jerryMarkt: Market = Market(name: "Jerry`s Market", product: appleInfo)
print("Market title: \(jerryMarkt.name), selling Item: \(jerryMarkt.product) won")
// Market title: Jerry`s Market, selling Item: Fruit(name: "delmont appple", price: 5000) won

 

 

 

구조체든 클래스든 저장 프로퍼티에 초기값을 미리 지정해도 상관 없음

 

다만, 의도와 맞지 않게 인스턴스가 사용될 가능성도 있고, 

인스턴스를 생성한 후에 일일이 필요한 값을 할당해야하는 번거러움 

 

 

만약에 저장 프로퍼티가 옵셔널로 선언 되었다면? 

굳이 초기값을 넣어줄 필요 없음 

 

 

옵셔널 저장 프로퍼티 

// 과일 정보
struct Fruit {
    
    // 과일 이름과 가격은 꼭 있어야 하니까 옵셔널로 하면 안됨
    var name: String 
    var price: Int
}

 

 

가게 정보에서 가게 이름은 반드시 있어야 하지만, 

가게 안에서 파는 물건에 대해서는 모를 수도 있음 

 

// 가게 정보
class Market {
    var name: String
    var product: Fruit?
    
    init(name: String) {
        self.name = name
    }
}


let jerryMarkt: Market = Market(name: "Jerry`s Market")
print("Market title: \(jerryMarkt.name)")
// Market title: Jerry`s Market

 

 

 

나중에 가게에서 파는 물건을 알게 되었다면?

 

let jerryMarkt: Market = Market(name: "Jerry`s Market")
jerryMarkt.product = appleInfo

print("Market title: \(jerryMarkt.name), selling Item: \(jerryMarkt.product!) won")
// Market title: Jerry`s Market, selling Item: Fruit(name: "delmont appple", price: 5000) won

 

※ 여기서 product는 Fruit? 라는 옵셔널이기 때문에

옵셔널 바인딩을 통해 안전하게 값을 추출해야 함

(다만, 여기서 강제 추출로 함)

 

 

 

지연 저장 프로퍼티 

호출이 있어야 초기화

lazy 키워드 사용

 

상수는 인스턴스가 와전히 생성되기 전에 초기화해야 하므로 

필요한 때 값을 할당하는 지연 저장 프로퍼티와 맞지 않음

 

따라서 지연 저장 프로퍼티는 var 키워드를 사용하여 선언 

 

 

지연 저장 프로퍼티 

struct Fruit {
    var name: String?
    var price: Int?
    
    init() {
        print("fruit init!!")
    }
}

class Market {
    var name: String = "jerry`s Market"
    lazy var product: Fruit = .init()
}


var jerryMarket: Market = .init()

 

 

실행하면 "fruit init!!"은 출력되지 않음

Market 클래스 내에 product 프로퍼티를 lazy 키워드를 사용하여

아직, product 라는 저장 프로퍼티가 초기화 되지 않았기 때문 

 

 

그런데 여기서 jerryMarket 인스턴스를 통해 product 라는 변수에 접근한다면?

 

jerryMarket.product = Fruit()
// fruit init!!

 

 

 

지연 저장 프로퍼티는 언제 쓰일까?

간단히, 필요할 때만 접근하기 때문에 

메모리를 효율적으로 관리

 

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

프로퍼티 3편 (프로퍼티 감시자)  (0) 2024.01.23
프로퍼티 2편 (연산 프로퍼티)  (0) 2024.01.22
구조체와 클래스의 차이  (0) 2024.01.18
클래스  (0) 2024.01.17
구조체  (0) 2024.01.17