클로저와 self

2024. 10. 23. 20:41·Programing Langauge/swift
반응형

클로저

간단하게 클로저를 먼저 정리해보자.

  • 함수는 이름이 있는 클로저
  • 클로저는 1급 객체이다.
  • 클로즈는 참조타입이므로 기본적으로 힙에 할당된다.
  • Closure란 내부 함수와 내부 함수에 영향을 미치는 주변 환경을 모두 포함한 객체이다.

클로저 캡처

  • 클로저 캡처란 매개변수나 지역변수가 아닌 외부 context를 사용하기 위해 주변 외부의 context를 참조하는 것
  • 클로저는 값을 캡처할 때, Value / Reference 타입에 관계 없이 모두 Reference 캡처를 사용한다. 즉 , 참조를 한다는 뜻

캡처 리스트 

  • 값 타입은 값을 복사해서 캡처 - 외부 요인에 의한 값 변경을 방지!
  • 참조 타입은 캡처리스트 내에서 weak, unowned 참조 선언 (강한 참조 해결)

클로저와 self 

@escaping 키워드

클로저와 self의 관계를 가기전에 @escaping 키워드에 대해 잠시 알아보자.

var 함수저장변수: (() -> Void)?

/// @escaping 키워드 파라미터가 지금 실행되고 있는 스코프를 벗어나서도 쓰인다.

func 탈출클로저(함수파라미터: @escaping () -> Void) {
    함수저장변수 = 함수파라미터 // 외부 변수에 클로저(참조타입) 저장되면 힙에 저장되어 오래쓰임 
    // 캡처현상이 발생 가능 O
}


/// 인풋(함수파라미터)가 힙(Heap)에 저장이 안됨(오랫동안 쓰이지 않음) ===> 캡처현상이 발생 X

func 기본클로저(함수파라미터: () -> Void) {
    함수파라미터() // 외부 스코프로 나가지 않음, 힙에 저장 x , 캡쳐핸상 발생 x
}

 


클래스에서 클로저

  self 캡처 여부 이유
탈출 클로저 O 변수를 소유하고 있는 self 자체를 캡처하기
때문에
기본 클로저 X 암시적으로 self를 참조

 

class 클래스 {
    var x = 10
    
    func doSomething() {
        탈출클로저 { in   
            self.x = 100 /// 명시적 self 참조, 나중에 호출시 실행
        }
        기본클로저 {   /// 즉시 실행
            x = 200 /// 암시적 self참조
        }
    }
}
  • 클래스에서 탈출 클로저는 항상 self를 붙혀야한다. 혹은 캡처 리스트 작성
  • 기본 클로저는 self를 붙히지 않아도 됨, 암시적으로 self를 참조

값타입에서 클로저

  self 캡처 여부 이유
탈출 클로저 오류 self에 대한 변경이 불가
값타입이니 값 복사가 일어나
원본을 바꿀 수 없으므로 
기본 클로저 X 암시적으로 self를 참조

 

struct 구조체 {   // 값타입
    var x = 10
    
    mutating func doSomething() {
        기본클로저 {
            x = 200          /// Ok  (암시적으로 self참조)
        }
        
        // ❌ 에러 발생
        탈출클로저 {
            self.x = 100 
        }                   
    }
}
  • 값 타입의 self 일경우 항상 암시적으로 self를 참조
  • 위의 예시에서 doSomething 함수 내부에서 탈출 클로저를 호출하는 것은 오류다.
  • mutating  함수 스코프에서 변수값을 바꾸는게 아닌 탈출클로저로 인해 외부 스코프에서 구조체(값타입)에 대해
    변경하는 것이기 때문에 잘못된 사용이다.

참고

 

Documentation

 

docs.swift.org

 

반응형

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

Dynamic Key decoding  (3) 2024.12.21
GC vs ARC  (1) 2024.12.13
swift 기본 타입  (0) 2024.10.18
디스패치 학습하기 (4) [ Extension Dispatch ]  (0) 2024.08.26
디스패치 학습하기 (3) [ Value Type Dispatch, Protocol Dispatch ]  (1) 2024.08.25
'Programing Langauge/swift' 카테고리의 다른 글
  • Dynamic Key decoding
  • GC vs ARC
  • swift 기본 타입
  • 디스패치 학습하기 (4) [ Extension Dispatch ]
Hamp
Hamp
남들에게 보여주기 부끄러운 잡다한 글을 적어 나가는 자칭 기술 블로그입니다.
  • Hamp
    Hamp의 분리수거함
    Hamp
  • 전체
    오늘
    어제
    • 분류 전체보기 (304)
      • CS (30)
        • 객체지향 (2)
        • Network (7)
        • OS (6)
        • 자료구조 (1)
        • LiveStreaming (3)
        • 이미지 (1)
        • 잡다한 질문 정리 (0)
        • Hardware (2)
        • 이론 (6)
        • 컴퓨터 그래픽스 (0)
      • Firebase (3)
      • Programing Langauge (37)
        • swift (32)
        • python (4)
        • Kotlin (1)
      • iOS (132)
        • UIKit (37)
        • Combine (1)
        • SwiftUI (32)
        • Framework (7)
        • Swift Concurrency (22)
        • Tuist (6)
        • Setting (11)
        • Modularization (1)
        • 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 (13)
        • 어노테이션 (1)
        • 튜토리얼 (11)
      • CI-CD (4)
      • Android (0)
        • Jetpack Compose (0)
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

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

  • 최근 글

  • 반응형
  • hELLO· Designed By정상우.v4.10.0
Hamp
클로저와 self
상단으로

티스토리툴바