본문 바로가기

Swift

[Swift] 프로퍼티(Property) / 메서드(Method) / 인스턴스(Instance)

728x90

프로퍼티(Property)

  • 클래스, 구조체, 열거형 등에 관련된 값

저장 프로퍼티(Stored Properties)

  1. 인스턴스의 변수 또는 상수를 의미해요.
  2. 종류
    1. 변수 저장 프로퍼티 : var 키워드를 사용해서 생성
    2. 상수 저장 프로퍼티 : let 키워드를 사용해서 생성
    3. 지연 저장 프로퍼티 : lazy var 키워드를 사용해서 생성: 프로퍼티를 호출하기 전 까지는 값을 가지지 않아요.
    4. class Baby { // This property is lazily initialized. lazy var firstWord: String = { print("Goo goo ga ga ... Mama!") return "Mama" }() init() { print("Baby Born!") } } let cuteBaby = Baby() // lazy 프로퍼티에 접근해야 값이 생성되요. //print(cuteBaby.firstWord)
    5. : 굳이 모든 저장 프로퍼티를 사용할 필요가 없을 때

연산 프로퍼티(Computed Properties)

  1. 특정 상태에 따른 값을 연산하는 프로퍼티에요.
  2. 접근자(Getter)와 설정자(Setter)
    • getter : 인스턴스 내/외부의 값을 연산하여 적절한 값을 돌려주는 역할
    • setter : 은닉화된 내부의 프로퍼티 값을 간접적으로 설정하는 역할
  3. 프로퍼티 감시자(Property Observers)
    • willSet : 값이 변경되기 직전에 호출되는 메서드
    • didSet : 값이 변경된 직후에 호출되는 메서드
  4. 프로퍼티의 값이 새롭게 할당될 때마다 호출이 되서, 값이 변경될 때 적절한 작업을 할 수 있어요.
class Temperature {
    var celsius: Double = 0 {
        willSet {
            print("Updating celsius from \\(celsius) to \\(newValue)")
        }
        didSet {
            print("celsius is set from \\(oldValue) to \\(celsius) now")
        }
    }

    var fahrenheit: Double {
        get {
            return celsius * 9 / 5 + 32
        }
        set {
            celsius = (newValue - 32) * 5 / 9
        }
    }
}

var temperature = Temperature()
temperature.celsius = 25
print("Fahrenheit: \\(temperature.fahrenheit)")

타입 프로퍼티(Type Properties)

  1. 인스턴스 프로퍼티(저장/연산 프로퍼티)와 다르게 타입 자체에 속하는 프로퍼티에요.
  2. 모든 인스턴스에서 공용으로 접근하고 값을 변경할 수 있는 변수 등을 정의할 때 유용해요.
  3. 종류
    1. 저장 타입 프로퍼티
      • 변수 또는 상수로 선언할 수 있어요.
      • 초기값을 설정해야 하고, 지연 연산이 됩니다.(그렇지만 lazy 키워드 사용은 X)
    2. 연산 타입 프로퍼티
      • 변수로만 선언할 수 있어요.
struct SomeStructure {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int = 42 {
        willSet {
            
        }
        didSet {
            
        }
    }
}

class SomeClass {
    static var storedTypeProperty = "Class value."
    class var overrideableComputedTypeProperty: Int {
        return 107
    }
}

// 접근 방법
print(SomeStructure.storedTypeProperty)  // "Some value."
print(SomeStructure.computedTypeProperty)  // 42

SomeStructure.computedTypeProperty = 30
print(SomeStructure.computedTypeProperty)  // 30

print(SomeClass.storedTypeProperty)  // "Class value."
print(SomeClass.overrideableComputedTypeProperty)  // 107

메서드(Method)

  • 클래스, 구조체, 열거형 등 특정 타입에 관련된 함수

인스턴스 메서드

  1. 특정 타입의 인스턴스에 속한 함수를 뜻해요.
  2. 인스턴스 내부의 프로퍼티 값을 변경하거나 특정 연산 결과를 반환하는 등 인스턴스와 관련된 기능을 실행해요.
  3. 자신의 프로퍼티 값을 수정할 때 클래스의 인스턴스 메서드는 크게 신경 쓸 필요가 없지만, 구조체나 열거형은 값타입이므로 메서드 내에서 인스턴스의 상태를 변경하려면 메서드에 mutating 키워드를 붙여야해요.
class Dog {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    func bark() {
        print("\\(name) says Woof!")
    }

    func celebrateBirthday() {
        age += 1
        print("\\(name) is now \\(age) years old!")
    }
}

// 인스턴스 생성
var myDog = Dog(name: "Buddy", age: 2)

// 인스턴스 메서드 호출
myDog.bark()  // 출력: Buddy says Woof!

// 생일을 축하하는 메서드 호출
myDog.celebrateBirthday()  // 출력: Buddy is now 3 years old!
struct Dog {
    var name: String
    var age: Int

    func bark() {
        print("\\(name) says Woof!")
    }

    // struct는 값 타입이므로 메서드 내에서 인스턴스의 상태를 변경하려면 mutating 키워드를 추가해야해요.
    mutating func celebrateBirthday() {
        age += 1
        print("\\(name) is now \\(age) years old!")
    }
}

// 인스턴스 생성
var myDog = Dog(name: "Buddy", age: 2)

// 인스턴스 메서드 호출
myDog.bark()  // 출력: Buddy says Woof!

// 생일을 축하하는 메서드 호출
myDog.celebrateBirthday()  // 출력: Buddy is now 3 years old!

타입 메서드(Type Method)

  1. 타입 자체에 호출이 가능한 메서드
  2. 종류
    1. static : 상속 후 메서드 재정의가 불가능
    2. class : 상속 후 메서드 재정의가 가능 (구조체에서는 class 타입 메서드 선언 불가)
struct MathUtility {
    // 타입 메서드 (static 키워드 사용)
    static func square(_ number: Double) -> Double {
        return number * number
    }
}

// 타입 메서드 호출
let result = MathUtility.square(4.0)
print("Square of 4.0 is \\(result)")
class Vehicle {
    // 타입 메서드 (class 키워드 사용)
    class func description() -> String {
        return "This is a vehicle."
    }
}

class Car: Vehicle {
    // 타입 메서드를 서브클래스에서 재정의
    override class func description() -> String {
        return "This is a car."
    }
}

// 타입 메서드 호출
print(Vehicle.description())  // 출력: This is a vehicle.
print(Car.description())      // 출력: This is a car.

인스턴스 생성 / 소멸

  • **이니셜라이저(Initializer)**를 정의해 저장 프로퍼티의 초깃값 설정 등을 할 수 있어요.
  • 클래스는 **디이니셜라이저(Deinitializer)**를 정의해 클래스의 인스턴스가 메모리에서 소멸되기 전에 할 작업을 할 수 있어요.

인스턴스 생성

  1. **이니셜라이저(Initializer)**를 정의해 초기화 과정을 직접 구현할 수 있어요.
  2. init 키워드를 사용해 이니셜라이저 메서드임을 표현해요.
  3. 구조체와 클래스의 인스턴스는 옵셔널 저장 프로퍼티가 아닌 모든 저장 프로퍼티에 초기값을 할당해야 합니다. 프로퍼티를 정의할 때 초기값을 할당하거나 이니셜라이저에서 초기값을 할당해야해요.
class Dog {
    var name: String
    var age: Int
    
    // Designated initializer
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    init(with name: String) {
        self.name = name
        self.age = 3
    }
    
    init(age: Int) {
        self.name = "Puff"
        self.age = age
    }
    
    init(_ age: Int) {
        self.name = "Puff"
        self.age = age
    }
}
struct Cat {
    var name: String = "Kitty"
    var age: Int
    
    init() {
        age = 10
    }
}

  1. 옵셔널 프로퍼티 타입은 초기화 과정에서 값을 초기화하지 않아도 되는 프로퍼티로, 값을 할당해주지 않으면 nil이 할당됩니다.
  2. 상수 프로퍼티로 선언하면 초기화 과정 이후에는 값을 변경할 수 없습니다.
class MyInfo {
		// 상수 프로퍼티로 선언되었기 때문에 초기화 과정 이후에는 값을 변경할 수 없습니다.
    let name: String
    var age: Int
    var job: String?
    
    init(name: String, _ age: Int, _ job: String? = nil) {
        self.name = name
        self.age = age
        self.job = job
    }
}

let sophie = MyInfo(name: "Sophie", 27)
print(sophie.job) // nil
// sophie.name = "Milky" // 이건 불가능해요.
  1. 멤버와이즈 이니셜라이저구조체는 사용자 정의 이니셜라이저를 구현하지 않으면 멤버와이즈 이니셜라이저를 기본으로 제공하지만, 클래스는 멤버와이즈 이니셜라이저를 지원하지 않아요.
  2. struct Size { var width: Double var height: Double } // 사용자 정의 이니셜라이저가 없어도 멤버와이즈 이니셜라이저가 만들어짐 let square1 = Size(width: 10.0, height: 30.0)
  3. : 프로퍼티의 이름으로 매개변수를 갖는 이니셜라이저
  4. 열거형(enum)에서 이니셜라이저
enum CompassPoint: String {
    case north, south, east, west

    // 이니셜라이저 정의
    init() {
        self = .north
    }
    
    // 사용자 정의 이니셜라이저
    init(with flag: String) {
        switch flag {
        case "S":
            self = .south
        case "E":
            self = .east
        case "W":
            self = .west
        default:
            self = .north
        }
    }
}

// 열거형 이니셜라이저 호출
let initialDirection = CompassPoint()
print(initialDirection) 

let myDirection = CompassPoint(with: "E")
print(myDirection)

// rawValue를 통한 이니셜라이저는 실패 가능한 이니셜라이저로 제공되요.
let newDirection = CompassPoint(rawValue: "NorthEast")
print(newDirection) // nil

실패 가능한 이니셜라이저(Failable Initializer)

  1. 이니셜라이저를 통해 인스턴스를 초기화할 수 없는 여러가지 예외 상황에서 정의해요.
  2. 실패 가능한 이니셜라이저는 실패했을 때 nil을 반환하므로 반환 타입이 옵셔널로 지정되요.
struct Temperature {
    var celsius: Double
    
    // 실패 가능한 이니셜라이저
    init?(fahrenheit: Double) {
        // 입력 값의 유효성을 검사하고 실패할 경우 nil 반환
        guard fahrenheit >= -459.67 else { return nil }
        self.celsius = (fahrenheit - 32) * 5 / 9
    }
}

// 실패 가능한 이니셜라이저 호출
if let boilingWater = Temperature(fahrenheit: 212) {
    print("Boiling water in Celsius: \\(boilingWater.celsius)")
} else {
    print("Invalid Fahrenheit value")
}

if let belowAbsoluteZero = Temperature(fahrenheit: -500) {
    print("This won't be printed since initialization fails.")
} else {
    print("Invalid Fahrenheit value")
}

함수를 사용한 프로퍼티 기본값 설정

  1. 저장 프로퍼티의 기본값을 설정할 때 클로저나 함수를 사용해 기본값을 제공할 수 있어요.
  2. 클로저 내부에서는 self 프로퍼티를 사용할 수 없고 인스턴스 메서드 호출이 불가능해요.
  3. 클로저나 함수의 반환 타입은 프로퍼티의 타입과 일치해야해요.
  4. UI 컴포넌트를 생성할 때 유용하게 쓰입니다! ✨
fileprivate let horizontalLine: UIView = {
    let view = UIView()
    view.backgroundColor = .lightGray.withAlphaComponent(0.5)
    return view
}()

인스턴스 소멸

  1. 클래스는 **디이니셜라이저(Deinitializer)**를 정의해 클래스의 인스턴스가 메모리에서 소멸되기 전에 할 작업을 할 수 있어요.
  2. 메모리에서 클래스의 인스턴스가 소멸되기 바로 직전에 호출되요.
  3. deinit 키워드를 사용해 디이니셜라이저를 구현만하면 자동으로 호출됩니다.
728x90

'Swift' 카테고리의 다른 글

[Swift] 클로저  (0) 2024.02.21
[Swift] 접근제어  (0) 2023.12.19
[Swift] 구조체(Struct) 와 클래스(Class)  (1) 2023.11.27
[Swift] Optional  (0) 2023.11.15
[Swift] 함수(Function)  (0) 2023.11.15