스위프트에서의 프로퍼티 (iOS 앱 개발)

개발자의 일상, @munondio 팔로우 해보세요!

프로퍼티는 변수의 다른 이름입니다. 클래스, 구조체, 열거 등 전체적으로 사용되는 변수를 프로퍼티라고 부릅니다.

프로퍼티의 종류에는 저장 프로퍼티, 연산 프로퍼티, 타입 프로퍼티가 있는데요. 순서대로 하나씩 알아보도록 하겠습니다.

저장 프로퍼티

저장 프로퍼티는 가장 일반적인 프로퍼티로써, 값을 저장하는 용도로 사용됩니다. 초기값을 설정 할 수 있고, 클래스 구조체에서는 인스턴스와 연관된 값을 저장합니다.

지연 저장 프로퍼티

지연 저장 프로퍼티는 프로퍼티가 처음으로 사용되기 전까지 초기값이 계산되지 않는 특성을 갖고 있습니다.

lazy 키워드를 선언 앞에 작성해서 사용할 수 있고, let은 지연 저장 프로퍼티로 사용할 수 없습니다.

연산 프로퍼티

실제로 값을 저장하지는 않고, get과 set 키워드로 값을 간접적으로 설정하거나 받습니다.

class Point
{
    var x = 0.0
    var y = 0.0
    
    init(x: Double, y: Double)
    {
        self.x = x
        self.y = y
    }
}
    
class Size
{
    var width = 0.0
    var height = 0.0
    
    init(width: Double, height: Double)
    {
        self.width = width
        self.height = height
    }
}
    
class Rect
{
    var startSpot: Point = Point(x: 0, y: 0)
    var size: Size = Size(width: 0.0, height: 0.0)
    
    var center: Point
    {
        get
        {
            let c: Point = Point(x: startSpot.x + size.width/2, y: startSpot.y + size.height/2)
            return c
        }
        set(newCenter)
        {
            startSpot.x = newCenter.x - size.width/2
            startSpot.y = newCenter.y - size.height/2
        }
    }
}

다음과 같이 Rect 클래스안에 center라는 연산 프로퍼티를 만들어봤는데요. 다음과 같이 사용될 수 있습니다.

let rect: Rect = Rect()
rect.startSpot = Point(x: 10, y: 10)
rect.size = Size(width: 100, height: 100)
    
// center의 get 사용
print(rect.center.x, rect.center.y)
    
// center의 set 사용
rect.center = Point(x: 200, y:200)
print(rect.startSpot.x, rect.startSpot.y)

타입 프로퍼티

타입 프로퍼티로는 인스턴스의 속성이 아닌, 타입에 따른 속성을 정의할 수 있습니다. static 키워드를 사용해서 값타입에서 타입 프로퍼티를 설정할 수 있고, class 키워드를 사용해서 클래스 타입에서 타입 프로퍼티를 설정할 수 있습니다. 값을 가져올때는 클래스의 이름을 통해서 가져올 수 있습니다.

타입 프로퍼티 예제

설명만으로는 약간 추상적이고, 이해가 가지 않을 수 있는데요. 예제를 통해 살펴보도록합시다.

struct AudioChannel
{
    static let level = 10
    static var maxLevel = 0
    
    var currentLevel: Int = 0
    {
        didSet
        {
            if currentLevel > AudioChannel.level
            {
                currentLevel = AudioChannel.level
            }
            if currentLevel > AudioChannel.maxLevel
            {
                AudioChannel.maxLevel = currentLevel
            }
        }
    }
}