728x90
프로퍼티(Property)
- 클래스, 구조체, 열거형 등에 관련된 값
저장 프로퍼티(Stored Properties)
- 인스턴스의 변수 또는 상수를 의미해요.
- 종류
- 변수 저장 프로퍼티 : var 키워드를 사용해서 생성
- 상수 저장 프로퍼티 : let 키워드를 사용해서 생성
- 지연 저장 프로퍼티 : lazy var 키워드를 사용해서 생성: 프로퍼티를 호출하기 전 까지는 값을 가지지 않아요.
- 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)
- : 굳이 모든 저장 프로퍼티를 사용할 필요가 없을 때
연산 프로퍼티(Computed Properties)
- 특정 상태에 따른 값을 연산하는 프로퍼티에요.
- 접근자(Getter)와 설정자(Setter)
- getter : 인스턴스 내/외부의 값을 연산하여 적절한 값을 돌려주는 역할
- setter : 은닉화된 내부의 프로퍼티 값을 간접적으로 설정하는 역할
- 프로퍼티 감시자(Property Observers)
- willSet : 값이 변경되기 직전에 호출되는 메서드
- didSet : 값이 변경된 직후에 호출되는 메서드
- 프로퍼티의 값이 새롭게 할당될 때마다 호출이 되서, 값이 변경될 때 적절한 작업을 할 수 있어요.
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)
- 인스턴스 프로퍼티(저장/연산 프로퍼티)와 다르게 타입 자체에 속하는 프로퍼티에요.
- 모든 인스턴스에서 공용으로 접근하고 값을 변경할 수 있는 변수 등을 정의할 때 유용해요.
- 종류
- 저장 타입 프로퍼티
- 변수 또는 상수로 선언할 수 있어요.
- 초기값을 설정해야 하고, 지연 연산이 됩니다.(그렇지만 lazy 키워드 사용은 X)
- 연산 타입 프로퍼티
- 변수로만 선언할 수 있어요.
- 저장 타입 프로퍼티
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)
- 클래스, 구조체, 열거형 등 특정 타입에 관련된 함수
인스턴스 메서드
- 특정 타입의 인스턴스에 속한 함수를 뜻해요.
- 인스턴스 내부의 프로퍼티 값을 변경하거나 특정 연산 결과를 반환하는 등 인스턴스와 관련된 기능을 실행해요.
- 자신의 프로퍼티 값을 수정할 때 클래스의 인스턴스 메서드는 크게 신경 쓸 필요가 없지만, 구조체나 열거형은 값타입이므로 메서드 내에서 인스턴스의 상태를 변경하려면 메서드에 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)
- 타입 자체에 호출이 가능한 메서드
- 종류
- static : 상속 후 메서드 재정의가 불가능
- 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)**를 정의해 클래스의 인스턴스가 메모리에서 소멸되기 전에 할 작업을 할 수 있어요.
인스턴스 생성
- **이니셜라이저(Initializer)**를 정의해 초기화 과정을 직접 구현할 수 있어요.
- init 키워드를 사용해 이니셜라이저 메서드임을 표현해요.
- 구조체와 클래스의 인스턴스는 옵셔널 저장 프로퍼티가 아닌 모든 저장 프로퍼티에 초기값을 할당해야 합니다. 프로퍼티를 정의할 때 초기값을 할당하거나 이니셜라이저에서 초기값을 할당해야해요.
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
}
}
- 옵셔널 프로퍼티 타입은 초기화 과정에서 값을 초기화하지 않아도 되는 프로퍼티로, 값을 할당해주지 않으면 nil이 할당됩니다.
- 상수 프로퍼티로 선언하면 초기화 과정 이후에는 값을 변경할 수 없습니다.
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" // 이건 불가능해요.
- 멤버와이즈 이니셜라이저구조체는 사용자 정의 이니셜라이저를 구현하지 않으면 멤버와이즈 이니셜라이저를 기본으로 제공하지만, 클래스는 멤버와이즈 이니셜라이저를 지원하지 않아요.
- struct Size { var width: Double var height: Double } // 사용자 정의 이니셜라이저가 없어도 멤버와이즈 이니셜라이저가 만들어짐 let square1 = Size(width: 10.0, height: 30.0)
- : 프로퍼티의 이름으로 매개변수를 갖는 이니셜라이저
- 열거형(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)
- 이니셜라이저를 통해 인스턴스를 초기화할 수 없는 여러가지 예외 상황에서 정의해요.
- 실패 가능한 이니셜라이저는 실패했을 때 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")
}
함수를 사용한 프로퍼티 기본값 설정
- 저장 프로퍼티의 기본값을 설정할 때 클로저나 함수를 사용해 기본값을 제공할 수 있어요.
- 클로저 내부에서는 self 프로퍼티를 사용할 수 없고 인스턴스 메서드 호출이 불가능해요.
- 클로저나 함수의 반환 타입은 프로퍼티의 타입과 일치해야해요.
- UI 컴포넌트를 생성할 때 유용하게 쓰입니다! ✨
fileprivate let horizontalLine: UIView = {
let view = UIView()
view.backgroundColor = .lightGray.withAlphaComponent(0.5)
return view
}()
인스턴스 소멸
- 클래스는 **디이니셜라이저(Deinitializer)**를 정의해 클래스의 인스턴스가 메모리에서 소멸되기 전에 할 작업을 할 수 있어요.
- 메모리에서 클래스의 인스턴스가 소멸되기 바로 직전에 호출되요.
- 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 |