오늘 찾아본 키워드
1. 초기화
2. 초기화 해제
3. self
초기화 (Initialization)
초기화는 인스턴스를 만들 때 반드시 필요한 작업이다.
이를 수행하지 않으면 객체가 제대로 동작하지 않을 수 있다.
초기화가 필요한 이유는 다음과 같다.
- 프로퍼티에 올바른 초기값 설정
- 객체 생성 시 필요한 설정 수행
- 다양한 생성 방법 제공(initializer overloading)
// 1. 올바른 초기값 설정
class User {
var name: String // 초기값 없이 선언
init(name: String) {
self.name = name // 초기값을 설정하여 사용해야한다.
}
}
let user1 = User(name: "Taenee")
let user2 = User() // Error!!
// 2. 객체 생성 시 필요한 설정 수행
class Sample {
var sample: String
init() {
print("sample 값을 설정합니다.")
self.sample = "default"
}
}
let sample = Sample() // "sample 값을 설정합니다." 출력
// 3.다양한 생성 방법 제공(initializer overloading)
class UserInfo {
var name: String
var age: Int
var job: String
init(name: String, age: Int, job: String) {
self.name = name
self.age = age
self.job = job
}
init(name: String, age: Int) {
self.name = name
self.age = age
self.job = "탐색중👀" // 직업 없을 수도 있으니까
}
}
let user1 = UserInfo(name: "Taeni", age: 31, job: "개발자")
let user2 = UserInfo(name: "Hong", age: 20)
초기화 해제(deinit)가 필요한 이유
초기화 해제는 메모리에서 객체가 제거될 때 실행되는 코드 블럭이다.
Swift의 ARC(Automatic Reference Counting)가 대부분의 메모리 관리를 자동으로 처리하지만, deinit 을 직접 수행하는 경우가 있다.
- 객체가 사라질 때 정리 하는 작업
- 메모리 누수 방지
// 1. 객체가 사라질 때 정리
// 네트워크 연결 해제, 파일 닫기, 리소스 정리 등의 작업을 수행할 때 직접 이 코드 블럭을 수행한다.
class FileHandler {
var fileName: String
init(fileName: String) {
self.fileName = fileName
print("\(fileName) 파일 초기화.")
}
deinit {
print("\(fileName) 파일 초기화 해제.")
}
}
var file: FileHandler? = FileHandler(fileName: "data.txt")
// "data.txt 파일 초기화." 출력
file = nil // "data.txt 파일 초기화 해제." 출력
// 2. 메모리 누수 방지
// 설명은 아래에 좀 더!!
import SwiftUI
class NetworkManager: ObservableObject {
var networkTask: (() -> Void)?
func setupTask() {
networkTask = { [weak self] in
print("\(self?.description ?? "self is nil")에서 네트워크 작업 실행")
}
}
deinit {
print("NetworkManager가 메모리에서 해제됨")
}
}
struct ContentView: View {
@StateObject private var networkManager = NetworkManager()
var body: some View {
VStack {
Button("네트워크 작업 설정") {
networkManager.setupTask()
}
}
}
}
// 네트워크 작업을 설정한 후, ContentView가 사라지면 NetworkManager도 해제된다.
Swift 는 위에 말했듯이 ARC를 사용해 메모리를 자동으로 관리하지만, 강한 참조 순환이 발생하면 객체에 메모리가 계속 남아 Memory Leak 문제가 생기는 경우가 있다.
예를 들어, 위의 코드에서 User 를 새로 인스턴스 화 해서 생성 후 이를 강한 참조로 갖게 된다면.
var user3: User? = User(name: “HarTaeni”)
var user4 = user3 // user4 는 user3의 객체를 바라보게 된다. (참조 카운트가 매겨진다.)
user3 = nil // 초기화 해제를 해도 user4의 참조 때문에 메모리에서 해제가 되지 않는다.
print(user4?.name) // “HarTaeni”
user4 = nil // 이렇게 설정해야 모두 해제 됨 -> 참조 카운트가 0이 되므로.
이 부분은 추후 더 자세히 다뤄보도록 할 예정🤔
결론적으로 [weak self]를 사용하여 강한 참조 순환을 방지한다고 생각하면 된다.
Self
현재 인스턴스를 가르키는 것으로,
같은 이름의 프로퍼티와 매개변수를 구분할 때 사용한다.
class Snack {
var taste: String
init(taste: String) {
self.taste = taste // self를 사용하여 프로퍼티와 매개변수 구분
}
func printTaste() {
print("이 과자는 \(self.taste) 맛 입니다.")
}
}
'iOS > Swift' 카테고리의 다른 글
Swift 에서의 프로퍼티(Property) (0) | 2025.03.21 |
---|---|
Swift 에서의 Generics(제너릭) (0) | 2025.03.20 |
SwiftUI 로 고차함수 예제코드 (0) | 2025.03.19 |
Swift 에서의 일급 함수 (First-Class Function) (0) | 2025.03.18 |
[Swift Playground] 코딩 배우기2 - 임의의 장소에 보석 놓기 (0) | 2025.03.17 |