소유권이란?

2026. 7. 14. 10:11·Programing Langauge/swift
반응형

👋 들어가기 전

최근 일과 사이드 프로젝트에 바쁘게 생활하고 있어, 기저 개념을 학습할 수 있는 시간과 기회가 부족했는데

팀동료께서 좋은 개념을 설명해주셔서 한번 학습해보려고 한다.

 

주제는 바로 제목과 같이 소유권이라는 개념과 함꼐 Swift 진영에서는 어떻게 다루고 있는 지 살펴보려고한다.


🏁 학습할 내용

  • 소유권은 무엇이고, 왜 필요한가?
    • Copyable과 ~Copyable
    • borrowing
    • consume
    • consuming
  • SIL 맛보기

🧐 소유권은 무엇이고,  왜 필요한가?

 

1️⃣ 소유권

아래 코드가 있을 떄, 메모리 관점에서 다음 지문들을 생각해보자.

let a = Data(...)
let b = a

a ----+
      |
      ↓
     Data
      ↑
      |
b ----+
  • 누가 Owner인가?
  • 언제 Owner가 바뀌는가?
  • 동시에 접근 가능한가?
  • 복사가 일어나는가?
  • 이동(move)이 일어나는가?

이런 내용들을 정의하는 개념이 바로 소유권이다.

그러면 왜 필요할까?

 

소유권은 해당 데이터가 메모리에 얼마나 머물 수 있는 지에 대한 생명주기와 깊은 연관이 있다.

 

 

2️⃣ 키워드

키워드를 통해, 소유권에 대한 세부 개념을 살펴보자.

 

🖨️ Copyable과 ~Copyable

  • Copyable
    • 타입의 인스턴스는 자유롭게 복사할 수 있다를 보장하는 프로토콜
    • 암묵적으로 대부분의 타입이 Copyable
  • ~Copyable
    • 반대로 복사가 불가능한 타입
    • 인스턴스 생명주기가 명확히 단 하나로 추적되므로, 구조체임에도 deinit 사용 가능
    • 시스템 프로그래밍 최적화를 위해,  메모리 관리나 리소스 해제등 무분별한 Copy를 막기위해 등장
struct A: Copyable {}
struct B: ~Copyable {}

 

우리가 배우는 소유권은 ~Copyable 상황에서 큰 힘을 발휘한다. Copyable에서는 크게 소유권이 의미가 없음

 

🔄 Move와 Copy,  Borrow와 Consume

Borrow와 Consume은 소유권을 어떻게 다룰지를 말하고,
Copy와 Move는 값을 어떻게 전달할지를 말한다.

 

 

소유권 관점

의미 값을 잠시 빌려 사용 소유권을 가져감
Ownership 이동 ❌ 없음 ✅ 있음
원래 Owner 계속 유지 더 이상 사용할 수 없음
사용 목적 읽기, 임시 접근 리소스 인계, 생명주기 종료
대표 키워드 borrowing consuming, consume

 

Value 전달 관점

의미 값을 하나 더 만든다 값을 새 Owner에게 넘긴다
메모리 새로운 값 생성 기존 값을 그대로 사용
원본 사용 ✅ 가능 ❌ 불가능
Owner 수 2명 이상 항상 1명
비용 복사 비용 발생 가능 매우 저렴(Ownership만 변경)

 

 

키워드

 

  • borrowing (매개변수/메서드 수식어)
    • 데이터를 복사하지 않고 기존 메모리 주소를 잠깐 빌려서 읽기 전용으로만 접근
      함수가 끝나도 원본 데이터는 그대로 유지
  • consuming (매개변수/메서드 수식어)
    • 데이터의 소유권을 함수 내부로 완전히 가져옴
    • 함수 내부에서 값을 수정하거나 활용할 수 있으며, 함수가 종료되는 순간 해당 데이터는 메모리에서 해제(deinit)됨
  • consume (연산자)
    • 코드 실행 도중 특정 변수나 상수의 소유권을 명시적으로 종료시키거나 다른 곳으로 넘길 때 사용하는 명령

 

 

분류 borrowing consuming consume
형태 매개변수 / 메서드 수식어 매개변수 / 메서드 수식어 단독 연산자 (consume 변수)
역할 읽기 전용으로 값 빌려오기 소유권을 가져와서 사용 후 파괴 변수의 소유권을 즉시 종결/이전
원본 유지 여부 ⭕ 유지됨 ❌ 함수 종료 후 원본 파괴 ❌ 연산 이후 기존 변수 사용 불가
값 수정 가능 여부 ❌ 불가 (읽기 전용) ⭕ 가능 (소유권이 있으므로) - (소유권 이전 목적)

 

struct User: ~Copyable {
    var name: String
}

// 1. borrowing 검증: 읽기만 가능하고 원본 유지
func printBorrowing(_ user: borrowing User) {
    print("Borrowing: \(user.name)")
    // user.name = "변경" // ❌ 컴파일 에러: borrowing 매개변수는 수정할 수 없음
}

// 2. consuming 검증: 소유권을 가져옴
func printConsuming(_ user: consuming User) {
    var localUser = user // 소유권이 넘어왔으므로 로컬 변수로 변경 가능
    localUser.name = "고길동"
    print("Consuming: \(localUser.name)")
    // 💡 함수가 끝나는 시점에 이 user 인스턴스는 메모리에서 해제됩니다.
}

// --- 검증 프로세스 ---
func testOwnership() {
    let originalUser = User(name: "홍길동")
    
    // [테스트 1] borrowing 호출
    printBorrowing(originalUser)
    print(originalUser.name) // ⭕ 정상 작동: originalUser가 그대로 살아있음
    
    print("----------------")
    
    // [테스트 2] consuming 호출
    printConsuming(originalUser)
    // 💡 뒤에서 originalUser를 더 이상 쓰지 않으므로, 컴파일러가 복사 없이 소유권을 넘겨버림!
    
    // ❌ 컴파일 에러 발생!
//     Error: 'originalUser' used after consume
//     print(originalUser.name)
}

func testConsumeOperator() {
    let targetUser = User(name: "이순신")
    
    // [테스트 3] consume 연산자 호출
    let newUser = consume targetUser // targetUser의 소유권을 newUser로 강제 이전
    
    print(newUser.name) // ⭕ 정상 작동: 이순신
    
    // ❌ 컴파일 에러 발생!
    // Error: 'targetUser' used after consume
    // print(targetUser.name)
}

 

아래는 consuming을 메서드로 사용했을 때와 파라미터에 명시했을 때 해석의 차이다.

 

  • consuming func는 객체가 스스로 생명주기를 마감하는 '자폭 버튼' 같은 메서드를 만들 때 쓰고,
  • consuming 파라미터는 함수가 외부 데이터를 입력받아 완전히 흡수하고 정리하는 '블랙홀' 같은 역할을 할 때 사용합니다.

 

// 1. 메서드에 붙었을 때: 점(.) 앞에 있는 녀석이 죽는다!
인스턴스.consuming메서드() 
// 💀 점 앞에 있던 '인스턴스' 사망

// 2. 파라미터에 붙었을 때: 괄호() 안에 든 녀석이 죽는다!
일반함수(consuming파라미터) 
// 💀 괄호 안에 넣었던 'consuming파라미터' 사망

struct File: ~Copyable {
    consuming func close() {
        // self의 소유권이 이 안으로 들어옴
        print("파일을 닫고 self를 메모리에서 해제합니다.")
    } // 💡 함수가 끝나는 이 시점에 self가 deinit 됨
}

let myFile = File()
myFile.close() // ⭕ 오케이!
// myFile.read() // ❌ 에러! 주체(self)인 myFile이 이미 사라짐

struct User: ~Copyable {
    var name: String
}

// 파라미터에 consuming이 붙음
func processUser(_ user: consuming User) {
    print("User \(user.name) 처리 중...")
} // 💡 함수가 끝나는 이 시점에 넘겨받은 user가 deinit 됨

let originalUser = User(name: "홍길동")
processUser(originalUser) // ⭕ 오케이! 소유권을 넘겨줌

// print(originalUser.name) // ❌ 에러! 외부 변수인 originalUser가 이미 사라짐

출처

반응형

'Programing Langauge > swift' 카테고리의 다른 글

defer  (0) 2026.01.31
퀵 헬프 주석  (0) 2026.01.14
Transferable  (0) 2025.12.14
@DynamicProperty  (0) 2025.10.24
@resultBuilder  (0) 2025.10.22
'Programing Langauge/swift' 카테고리의 다른 글
  • defer
  • 퀵 헬프 주석
  • Transferable
  • @DynamicProperty
Hamp
Hamp
남들에게 보여주기 부끄러운 잡다한 글을 적어 나가는 자칭 기술 블로그입니다.
  • Hamp
    Hamp의 분리수거함
    Hamp
  • 전체
    오늘
    어제
    • 분류 전체보기 (341) N
      • CS (30)
        • 객체지향 (2)
        • Network (7)
        • OS (6)
        • 자료구조 (1)
        • LiveStreaming (3)
        • 이미지 (1)
        • 잡다한 질문 정리 (0)
        • Hardware (2)
        • 이론 (6)
        • 컴퓨터 그래픽스 (0)
      • Firebase (3)
      • Programing Langauge (42) N
        • swift (35) N
        • python (6)
        • Kotlin (1)
      • iOS (135)
        • UIKit (37)
        • Combine (1)
        • SwiftUI (34)
        • Framework (7)
        • Swift Concurrency (22)
        • Tuist (6)
        • Setting (11)
        • Modularization (2)
        • Instruments (6)
      • PS (59)
        • 프로그래머스 (24)
        • 백준 (13)
        • LeetCode (19)
        • 알고리즘 (3)
      • Git (18)
        • 명령어 (4)
        • 이론 (2)
        • hooks (1)
        • config (2)
        • action (7)
      • Shell Script (2)
      • Linux (6)
        • 명령어 (5)
      • Spring (21)
        • 어노테이션 (6)
        • 튜토리얼 (14)
      • CI-CD (4)
      • Android (0)
        • Jetpack Compose (0)
      • AI (21)
        • 이론 (10)
        • MCP (1)
        • LangGraph (10)
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    lifecycle
    백준
    property
    concurrency
    UIKit
    Spring
    AVFoundation
    boostcamp
    IOS
    Tuist
    투포인터
    SwiftUI
    GIT
    protocol
    dispatch
    프로그래머스
    CS
    Swift
    dp
    dfs
  • 최근 댓글

  • 최근 글

  • 반응형
  • hELLO· Designed By정상우.v4.10.0
Hamp
소유권이란?
상단으로

티스토리툴바