프로그래밍iOS 개발자

스위프트에서 스택 할당과 힙 할당은 어떻게 작동합니까? 객체가 스택이나 힙에 배치되는 경우는 언제이며, 성능 및 객체의 생명 주기에 어떤 영향을 미칩니까?

Hintsage AI 어시스턴트로 면접 통과

답변

스위프트에서 값 타입(value types)인 struct, enum, tuple은 일반적으로 스택에 배치되고, 참조 타입(reference types)인 class는 힙에 배치됩니다.

스택 할당은 빠르고 자동화되어 있으며 짧은 생명 주기의 지역 변수를 저장하는 데 사용됩니다. 힙 할당은 추가 비용이 필요하며 불확실한 생명 주기 또는 크기를 가진 객체에 사용됩니다.

예:

struct Point { var x: Int; var y: Int } let p1 = Point(x: 2, y: 3) // 스택 class Node { var value: Int; init(value: Int) { self.value = value } } let n1 = Node(value: 5) // 힙

세부사항:

  • 스위프트 컴파일러/옵티마이저는 struct를 class에 포함되거나 컬렉션에 배치된 경우 힙에 저장할 수 있습니다.
  • 값 타입은 전달 시 복사되며, 이는 일반적으로 스택에서 복사되지만, 스위프트는 컬렉션에 대해 copy-on-write을 구현합니다.
  • 힙 할당은 객체의 생명 주기를 제어해야 합니다(ARC). 스택 객체는 범위를 벗어날 때 자동으로 파괴됩니다.

성능: 스택 할당은 힙 메모리 작업 및 객체 생명 주기 관리가 필요 없기 때문에 더 빠릅니다.

트릭 질문

모든 구조체(struct)는 항상 스택에만 배치되나요?

답변:
아니요! 구조체는 값 타입이지만, 클래스 내부, 배열, 사전 안에 있거나 클로저의 캡처된 값으로 사용될 때 컴파일러가 힙에 저장할 수 있습니다. 예:

class Box { var point: Point init(point: Point) { self.point = point } } let box = Box(point: Point(x: 1, y: 2))

여기서 Point의 인스턴스는 Box 클래스에 속하므로 힙에 저장됩니다.

주제에 대한 세부적인 실수의 실제 사례


이야기

개발자는 큰 구조체가 항상 스택에 있을 것이라고 생각하고 구조체의 성능을 최적화하려 했으나, 컬렉션(Array, Dictionary)이 힙 할당을 사용한다는 사실을 간과하여 프로젝트에서 예상치 못한 메모리 사용량 증가를 초래했습니다.


이야기

프로젝트는 클로저가 구조체의 값을 캡처하여 힙에 저장됨을 고려하지 않았고, 이는 변수의 생명 주기를 증가시켜 메모리 누수를 초래했습니다. 자동으로 범위를 벗어날 때 해제될 것이라고 예상했습니다.


이야기

copy-on-write을 이해하지 못하고 무거운 구조체의 배열을 사용함으로써, 스레드 간 컬렉션을 전송할 때 예상치 못하게 비싼 복사 작업이 발생하여 성능이 저하되고 UI에 지연이 발생했습니다.