1. Swift 메모리 구조의 이해
프로그램이 운영체제로부터 할당받는 대표적인 메모리 공간
1-1. Code 영역
프로그램의 실행 코드가 저장되는 공간
컴파일된 소스 코드와 프로그램의 명령어들이 저장됨
이 영역은 읽기 전용이며, 프로그램이 실행되면서 수정 X
1-2. Data 영역
전역 변수(global variables), 정적 변수(static variables), 상수(constants)가 저장되는 곳
프로그램 시작 시 할당 → 종료시 데이터 초기화
1-3. Stack(스택) 영역
값타입(value Type)이 저장되는 영역
소스코드가 컴파일러에 의해 기계어로 변환되는 시점(컴파일 타임)에 크기가 결정
함수 호출과 관련된 정보를 저장하는 데 사용
함수가 호출될 때마다 해당 함수의 로컬 변수(local variables),
함수 매개변수(parameters), 반환 주소(return address)
그리고 함수 호출에 필요한 기타 정보가 스택에 저장
함수가 실행을 마치면 해당 함수와 관련된 데이터가 스택에서 제거됨
후입선출 구조를 가짐
1-4. Heap(힙) 영역
참조타입(reference Type)이 저장되는 영역
프로그램 실행 중(런타임) 동적으로 할당된 데이터가 저장되는 곳
런타임 중에 메모리 할당이 필요한 경우 사용, 개발자가 직접 제어 가능
힙에 저장된 데이터는 직접적으로 포인터를 통해 접근(참조) 가능
힙은 스택과 달리 메모리의 자유 공간을 사용하여 데이터를 저장하므로,
크기나 수명에 대한 동적인 요구에 대응 가능
2. ARC 개념의 이해
ARC : Automatic(오토메틱) Reference(레퍼런스) Counting(카운팅)의 약자
ARC를 사용 → Heap 영역 객체 메모리 자동 관리
'Heap' 영역 객체에 대한 Strong Reference(강한 참조) count를 추적,
객체가 필요 없을 때 (참조 count가 없을 때) 해당 객체에 대한 메모리를
자동 해제하는 방식으로 메모리 관리
2-1. Strong Reference (강한 참조)
변수 or 상수는 강한 참조를 함.
객체에 대한 강한 참조 count가 증가되어 있다면, 해당 객체는 메모리에는 유지
class Person {
var name: String
init(name: String) {
self.name = name
}
}
var person1: Person? = Person(name: "Alice") // strong 참조
var person2 = person1 // 또 다른 strong 참조
// person1이 nil이 되더라도 person2가 여전히 strong 참조를 가지고 있으므로 객체는 메모리에 유지됨
person1 = nil
2-2. Circular References (순환 참조)
ARC 작동 방식의 특성상 두 객체가 서로를 강하게 참조하는 경우, 순환참조가 발생
두 객체 모두 더이상 사용되지 않더라도 두 객체가 서로를 강하게 참조하는 경우,
강한참조 'count'가 감소하지 않아, 메모리에서 해제되지 못하고
메모리가 누수되는 문제가 발생
↓
약한 참조(weak reference) 및 미소유 참조(unowned reference) 같은
다른 참조 유형을 사용 가능
class Person {
var name: String
var pet: Pet? // Person이 소유하는 Pet
init(name: String) {
self.name = name
}
}
class Pet {
var species: String
var owner: Person? // Pet을 소유하는 Person
init(species: String) {
self.species = species
}
}
var person: Person? = Person(name: "Alice") // Person 클래스의 인스턴스를 생성
var pet: Pet? = Pet(species: "Dog") // Pet 클래스의 인스턴스를 생성
person?.pet = pet // Person 클래스의 pet에 Pet 인스턴스를 할당
pet?.owner = person // Pet 클래스의 owner에 Person 인스턴스를 할당
2-3. Weak Reference (약한 참조)
약한 참조는 Strong Reference(강한 참조)와는 달리 객체의 참조 count 증가 X
객체의 생명 주기에 영향을 주지 않음, 참조 유지 가능
class Person {
var name: String
weak var friend: Person? // 약한 참조
init(name: String) {
self.name = name
}
}
var person1: Person? = Person(name: "Alice")
var person2: Person? = Person(name: "Bob")
person1?.friend = person2
person2?.friend = person1
// person1이 메모리에서 해제됨, 그에 따라 person1과 연결된 모든 객체의 참조 카운트가 감소됨
person1 = nil
2-4. Unowned Reference (미소유 참조)
미소유 참조는 약한 참조와 유사
'optional(옵셔널)' 값 아님, 'nil'로 설정 불가능
↓
객체가 메모리에서 해제될 때 자동으로 'nil'로 설정
참조하는 객체가 이미 메모리에서 해제된 상태에서 접근하려 한다면, '런타임 에러'가 발생
↓
사용 시점에 객체가 이미 해제되지 않았다고 확신할 수 있는 경우에 사용해야 함
class Country {
var name: String
var capital: City!
init(name: String, capitalName: String) {
self.name = name
self.capital = City(name: capitalName, country: self)
}
}
class City {
var name: String
unowned var country: Country // 미소유 참조
init(name: String, country: Country) {
self.name = name
self.country = country
}
}
'IOS > Swift-Study' 카테고리의 다른 글
[Swift-Study] iOS 앱 개발 숙련 1주차 - 내부 저장소 (0) | 2024.04.12 |
---|---|
[Swift-Study] iOS 앱 개발 숙련 1주차 - 네트워크 통신 (0) | 2024.04.12 |
[Swift-Study] 베이직반 2회차 - 1회차 복습, Closure 활용 VC 간 통신 (0) | 2024.04.11 |
[Swift-Study] Swift 베이직반 1회차 - Xcode, 함수와 클로저, 변수와 상수 (0) | 2024.04.11 |
[Swift-Study] IOS 앱 개발 입문 1주차 - 간단 디버깅 (0) | 2024.04.02 |