앱 개발을 하다 보면 자료구조나 메모리 구조에 대한 이해가 코드 안정성과 성능에 직결됩니다.
오늘은 Swift에서 자주 쓰이는 배열, 큐, 스택과 함께, 메모리 관리의 핵심인 ARC와 순환 참조 문제까지 정리해보겠습니다.
07.29(화)
제가 이해하고 공부 한대로 작성한 내용이다 보니 , 정확한 정보가 아닐수도 있습니다
고쳐야 할 부분이 있다면 , 편하게 애기 해주시면 감사 하겠습니다🙏🏻
var numbers = [1, 2, 3, 4, 5]
numbers.append(6)
print(numbers) // [1, 2, 3, 4, 5, 6]
📌 사용 예시
struct Queue<T> {
private var elements: [T] = []
mutating func enqueue(_ element: T) {
elements.append(element)
}
mutating func dequeue() -> T? {
return elements.isEmpty ? nil : elements.removeFirst()
}
}
📌 사용 예시
struct Stack<T> {
private var elements: [T] = []
mutating func push(_ element: T) {
elements.append(element)
}
mutating func pop() -> T? {
return elements.popLast()
}
func peek() -> T? {
return elements.last
}
}
📌 사용 예시
구역 | 설명 |
---|---|
Stack | 함수 호출, 지역 변수 저장 |
Heap | 클래스 인스턴스 등 동적 메모리 저장 |
Code | 실행 코드 저장 영역 |
Data | 전역 변수, 정적 변수 저장 |
두 개 이상의 객체가 서로를 강하게 참조(strong
)하면, 서로 해제가 안 되는 문제가 발생합니다.
class Person {
var name: String
var pet: Pet?
init(name: String) {
self.name = name
print("👤 \(name) 초기화됨")
}
deinit {
print("👤 \(name) 해제됨")
}
}
class Pet {
var owner: Person?
init() {
print("🐶 Pet 초기화됨")
}
deinit {
print("🐶 Pet 해제됨")
}
}
do {
let person = Person(name: "Alice")
let pet = Pet()
person.pet = pet
pet.owner = person // 🔁 서로 강한 참조 → 순환 참조 발생
}
❌ deinit
이 호출되지 않음 → 메모리 누수 발생
weak
키워드 사용weak
참조는 ARC의 참조 카운트에 영향을 주지 않으며, 자동으로 nil
처리됩니다.
class Pet {
weak var owner: Person? // 🔑 약한 참조로 순환 참조 해결
}
class Person {
var name: String
var pet: Pet?
init(name: String) {
self.name = name
print("👤 \(name) 초기화됨")
}
deinit {
print("👤 \(name) 해제됨")
}
}
class Pet {
weak var owner: Person?
init() {
print("🐶 Pet 초기화됨")
}
deinit {
print("🐶 Pet 해제됨")
}
}
do {
let person = Person(name: "Alice")
let pet = Pet()
person.pet = pet
pet.owner = person
}
👤 Alice 초기화됨
🐶 Pet 초기화됨
👤 Alice 해제됨
🐶 Pet 해제됨
✔️ deinit
이 정상적으로 호출되어 메모리 누수가 해결됨
weak
, unowned
는 상황에 따라 적절히 선택하여 안정적인 코드 구조를 만드세요.🧑💻 이 글이 Swift 개발 입문자 또는 중급자에게 기초를 다시 정리하는 데 도움이 되었기를 바랍니다.
궁금한 점이나 더 다뤄줬으면 하는 주제가 있다면 댓글로 남겨주세요!