메모리 구조
메모리의 구조는 크게 코드 영역 / 데이터 영역 / 힙 영역 / 스택 영역으로 나뉜다. 각각에 대해 알아보자
코드
데이터
- 전역변수가 저장되는 영역이다.
- 앱의 실행부터 종료까지 사용가능한 요소가 저장된다.
- static으로 선언된 변수가 저장된다.
힙
- class와 같은 참조타입의 실제 데이터가 할당된다.
스택
- struct, enum과 같은 값타입이 할당된다.
- 참조타입의 포인터가 할당된다.
Class, Struct
Struct
- 특정 공간(스택 영역)에 모든 데이터가 저장된다.
- let으로 struct를 생성 시, stuct 전체가 수정이 불가능하다.
- var로 struct를 생성 시, 해당 stuct는 접근이 가능하며 내부 프로퍼티가 var이냐 let이냐에 따라 각 프로퍼티에 접근할 수 있다.
Class
- 클래스를 let으로 생성 할 경우, 스택 영역에 저장된 class의 포인터(주소값)을 잠그는 것이다.
- 따라서 클래스의 주소를 수정할 수 없다는 의미이며, 해당 포인터가 가리키는 프로퍼티는 접근이 가능하다.
- 해당 프로퍼티가 let이냐 var냐에 따라 각 프로퍼티의 접근 가능 여부가 결정된다.
저장 프로퍼티
프로퍼티는 선언할 때 초기화를 하거나, init에서 초기값을 주거나, 옵셔널로 설정해야한다.
지연 저장 프로퍼티
넷플릭스를 보다 보면, 내가 선택한 영화만 미리보기가 재생되는 것을 확인할 수 있다. 유저가 선택하지 않는 영화의 미리보기를 모두 앱 실행 시, 저장해서 대기하고 있는 것은 비효율적일 것이다. 이때 지연 저장 프로퍼티 lazy를 사용한다.
지연 저장 프로퍼티는 클래스의 인스턴스를 생성하더라도, 해당 프로퍼티를 호출하지 않는다면 초기화되지 않는다.
(초기화는 나중에 되지만, 초기값은 가지고 있어야 한다.)
let으로 선언된 상수는 인스턴스가 생성되기 전에, 값을 항상 갖고 있어야 한다. 따라서 lazy는 let에 사용할 수 없고 lazy var로 사용한다.
타입 저장 프로퍼티
타입 저장 프로퍼티는 호출 순간 메모리(데이터 영역)에 올라가며, 앱이 종료될 때까지 유지된다. 인스턴스 저장 프로퍼티와 달리, 타입 자체에 속하기 때문에 인스턴스 생성 여부와 상관 없이 사용할 수 있다. 인스턴스를 몇개나 생성했는지와 상관없이, 타입 프로퍼티의 값은 한개이다.
사용법은 변수명 앞에 static을 붙이며, lazy로 동작하기 때문에 let으로 선언된 상수에 사용할 수 없다. 호출 시점에 메모리에 올라간다.
Any, AnyObject
- 지금까지 하나의 타입으로 배열을 선언했던 것([Int], [String]...)과 달리, 여러타입에 대응할 수 있다.
- 담고 있는 요소들의 실제 타입은 런타임 시점에 결정된다.
- 따라서 값을 안전하기 사용하기 위해 적절한 타입캐스팅이 필요하다.
Any
AnyObject
- 모든 클래스의 인스턴스를 담을 수 있다.
- 프로토콜에서 클래스의 제약을 설정하는데 사용된다.
타입 캐스팅
타입캐스팅을 통해 원하는 프로퍼티에 접근할 수 있도록 설정한다.
as as? as!
as
- 캐스팅에 대한 성공을 확신할 수 있는 경우(부모 클래스의 타입임을 알고 있을 때 등)에 as를 사용한다.
as?
- 옵셔널 반환 타입으로 실패할 경우 nil을 반환한다.
as!
- 실패할 경우 런타임 오류가 발생한다.
is
- 어떤 클래스의 인스턴스 타입인지 확인할 때 사용한다.
- 화면 전환 시에 많이 사용
class School {
...
}
class HighSchool : School {
...
}
관계 일 때, HighSchool의 인스턴스 highshool is School은 true이다.