Swift의 이니셜라이저
Swift의 init은 클래스, 구조체, 열거형에서 새로운 인스턴스를 생성하는데 필수적인 요소이다.
init 의 역할
Swift에서 init은 객체가 생성될 때 호출되는 생성자(initializer) 역할을 한다. 클래스, 구조체, 열거형 모두 init 키워드를 사용할 수 있으며 이를 통해 초기 속성 값을 부여하거나 특정 로직을 실행할 수 있다.
struct User {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
let user = User(name: "Park", age: 27)
init과 deinit
init은 객체가 생성될 때 호출되는 메서드이고 deinit은 구조체와 열거형에는 존재하지 않고 클래스의 인스턴스가 해제될 때 호출된다.
class TestClass {
init() {
print("객체 생성")
}
deinit {
print("객체 해제")
}
}
var test: TestClass? = TestClass() // 객체 생성 출력
test = nil // 객체 해제 출력
기본 이니셜라이저(Default Initialzer)
구조체와 클래스에서 프로퍼티가 기본값을 가지면, Swift는 자동으로 기본 이니셜라이저를 제공한다.
struct Car {
var brand = "현대"
var model = "아반떼"
}
let myCar = Car() // 기본 이니셜라이저 사용
print(myCar.barnd) // "현대"
멤버와이즈 이니셜라이저(Memberwise Initializer)
구조체는 자동으로 멤버와이즈 이니셜라이저를 제공하며, 모든 프로퍼티를 포함하는 초기화 메서드를 생성한다.
struct Point {
var x: Int
var y: Int
}
let point = Point(x: 10, y: 20)
하지만 클래스에서는 멤버와이즈 이니셜라이저가 존재하지 않기 때문에 프로퍼티에 기본값이 없을 경우 반드시 init을 직접 구현해야 한다.
class Person {
var name: String
init(name: String) { // 직접 이니셜라이저를 구현해야 한다.
self.name = name
}
}
다양한 init 사용법
1. 기본 init
가장 기본적인 형태의 이니셜라이저이다.
struct Animal {
var name: String
init(name: String) {
self.name = name
}
}
let dog = Animal(name: "Dog")
2. 옵셔널 프로퍼티와 init
프로퍼티가 옵셔널이면, 기본적으로 nil을 가질 수 있어 init에서 값을 꼭 할당하지 않아도 된다.
class Book {
var title: String?
}
let myBook = Book() // title은 nil
3. 기본값이 있는 init
기본값을 설정하면 특정값을 넣지 않아도 인스턴스를 생성할 수 있다.
struct Laptop {
var brand: String = "Apple"
var model: String
init(model: String) {
self.model = model
}
}
let macbook = Laptop(model: "MacBook Pro") // brand는 "Apple"
4. 사용자 정의 init
이니셜라이저 내부에서 특정 로직을 수행할 수도 있다.
struct Temperature {
var celsius: Double
init(fahrenheit: Double) {
self.celsius = (fahrenheit - 32) * 5/9
}
}
let temp = Temperature(fahrenheit: 98.6)
print(temp.celsius) // 37.0
convenience init(편의 이니셜라이저)
convenience init은 추가적인 이니셜라이저를 제공할 때 사용하며, 반드시 designated init 키워드를 호출해야 한다. 단, 구조체와 열거형에서는 convenience를 사용할 수 없다.
class User {
var name: String
var age: Int
init(name: String, age: Int) { // 지정 이니셜라이저
self.name = name
self.age = age
}
convenience init(name: String) { // 편의 이니셜라이저
self.init(name: name, age: 0) // 지정 이니셜라이저 호출 필수
}
}
let user1 = User(name: "Alice", age: 30)
let user2 = User(name: "Bob") // 편의 이니셜라이저 사용
상속과 init
1. required init
required 키워드는 서브클래스에서 반드시 구현해야 하는 이니셜라이저를 의미한다.
예시로는 주로 사용하는 TableView 를 구현할 때 cell을 커스텀 셀로 만들어줄 때 UITableViewCell 클래스를 상속받아 작성하는데 그곳에서도 required init을 사용한 경우가 존재한다.
open class UITableViewCell: UIView {
...
public required init?(coder: NSCoder) {
super.init(coder: coder)
}
...
}
class customCell: UITableViewCell {
...
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
...
}
2. override init
부모클래스의 init 을 오버라이드 할 때 사용한다.
class Vehicle {
var speed: Int
init(speed: Int) {
self.speed = speed
}
}
class Car: Vehicle {
override init(speed: Int) {
super.init(speed: speed)
print("Car initialized!")
}
}
let myCar = Car(speed: 100) // "Car initialized!" 출력
failable init (실패 가능한 이니셜라이저)
객체 생성에 실패할 가능성이 있는 경우 init? 을 사용하여 nil 을 반환할 수 있다. (required init 부분의 예시 코드에도 init? 으로 작성된 것을 확인할 수 있다.)
struct Product {
var name: String
var price: Int
init?(name: String, price: Int) {
if price < 0 {
return nil // 가격이 음수면 객체 생성 실패
}
self.name = name
self.price = price
}
}
let validProduct = Product(name: "Laptop", price: 1000) // 정상 생성
let invalidProduct = Product(name: "Invalid", price: -1) // nil 반환'TIL(Today I Learned)' 카테고리의 다른 글
| Swift의 ARC (0) | 2025.03.01 |
|---|---|
| 2025.02.24 Today I Learned (0) | 2025.02.24 |
| 2025.02.05 Today I Learned (0) | 2025.02.05 |
| 2025.01.24 Today I Learned (0) | 2025.01.24 |
| 2025.01.16 Today I Learned (1) | 2025.01.16 |