가. 큐(Queue) 구현하기
struct Queue {
var nums: [Int] = []
// 데이터 삽입
mutating func enqueue(_ num: Int) {
nums.append(num) // 배열에 순서대로 삽입
}
// 데이터 제거
mutating func dequeue() {
if !nums.isEmpty {
nums.removeFirst() // 선입 선출로 제거
}
}
// 현재 상태 출력
func status() {
print(nums)
}
}
var a = Queue()
a.enqueue(3)
a.enqueue(4)
a.status() // [3, 4] 출력
a.dequeue()
a.status() // [4] 출력
→ 정상 작동 확인
나. 스택(Stack) 구현하기
struct Stack {
var stringArr: [String] = []
// 데이터 삽입
mutating func push(_ element: String) {
stringArr.append(element) // 배열에 순서대로 삽입
}
// 데이터 제거
mutating func pop() {
stringArr.removeLast() // 후입 선출로 제거 (최상단 값이 제거되어야 하므로)
}
// 최상단 값 반환
func peek() -> String {
return stringArr.last ?? "" // stringArr.last는 옵셔널 값이므로 기본값 설정
}
}
var stack = Stack()
stack.push("A")
stack.push("B")
print(stack.peek()) // "B" 출력
stack.pop()
print(stack.peek()) // "A" 출력
→ 정상 작동 확인
가. 순환 참조 문제 구현
class Person {
var name: String
var pet: Pet?
init(name: String, pet: Pet? = nil) {
self.name = name
self.pet = pet
}
// 메모리에서 해제 시 출력
deinit {
print("\(name) 메모리에서 해제되었습니다.")
}
}
class Pet {
var name: String
var owner: Person
init(name: String, owner: Person) {
self.name = name
self.owner = owner
}
// 메모리에서 해제 시 출력
deinit {
print("\(name) 메모리에서 해제되었습니다.")
}
}
var person: Person? = Person(name: "Bambu")
var cat: Pet? = Pet(name: "Duri", owner: person!)
person!.pet = cat
cat = nil
person = nil
→ person은 pet 속성으로 cat을 참조하고 있음
→ cat은 owner 속성으로 person을 참조하고 있음
→ cat을 nil로 할당하더라도 person은 여전히 pet 속성으로써 cat을 계속 참조하고 있으므로 cat 인스턴스는 메모리에서 해제되지 않음
→ 메모리에서 해제되지 않은 cat 인스턴스는 owner 속성으로써 person을 계속 참조하고 있으므로 person을 nil로 할당하더라도 메모리에서 해제되지 않음
⇒ 즉, 순환 참조 발생으로 두 인스턴스 모두 메모리에서 해제되지 않음
class Person {
var name: String
weak var pet: Pet? // 약한 참조로 변경
init(name: String, pet: Pet? = nil) {
self.name = name
self.pet = pet
}
deinit {
print("\(name) 메모리에서 해제되었습니다.")
}
}
→ pet 프로퍼티를 약한 참조로 변경하여 참조 카운트가 되지 않도록 함
var person: Person? = Person(name: "Bambu")
var cat: Pet? = Pet(name: "Duri", owner: person!)
person!.pet = cat
cat = nil // Duri 메모리에서 해제되었습니다. 출력
person = nil // Bambu 메모리에서 해제되었습니다. 출력
→ cat을 nil로 할당 시 person은 cat을 약한 참조하고 있으므로 참조 카운팅이 0인 cat 인스턴스는 메모리에서 해제됨
→ cat이 메모리에서 해제되었으므로 person을 참조하고 있는 인스턴스는 존재하지 않음 - person을 nil로 할당 시 메모리에서 해제됨
⇒ 순환 참조가 해소되어 두 인스턴스 모두 정상적으로 메모리에서 해제
튜터님께서 랜덤 색상 변경 앱, 카운트 앱을 스토리보드, UIKit 코드, SwiftUI 3가지 방법으로 구현 시연
💡 현업에서 스토리보드를 (거의) 사용하지 않는 이유?
→ 여러 화면 표시 - 느려짐
→ 협업 시 혼란을 줄 가능성이 매우 큼!
: 모든 부분이 코드로 이루어져있지 않으므로 어떤 설정이 변하였는지 한번에 알기도 어렵고 커스텀 뷰를 재사용하기도 힘들다는 큰 단점이 있음
UIKit와 SwiftUI 서로 장단점이 있어 모두 사용하므로 둘다 알아야 함