Swift 클로저(Closures) & 객체지향 프로그래밍(OOP) 정리

Ios_Roy·2025년 7월 30일
0

TIL

목록 보기
14/25
post-thumbnail

1. 클로저 (Closures)

📌 클로저란?

클로저는 기능을 캡슐화한 코드 블록으로, 다음과 같은 특징을 가집니다:

  • 변수나 상수에 저장 가능
  • 다른 함수의 인자로 전달 가능
  • 코드에서 일급 객체처럼 사용 가능

🔤 문법 구조

{ (매개변수) -> 반환타입 in
    실행 코드
}

✅ 기본 클로저 예제

let greet = { (name: String) -> String in
    return "Hello, \(name)!"
}

print(greet("Alice")) // 출력: Hello, Alice!

✅ 함수에 클로저 전달하기

func performAction(action: () -> Void) {
    action()
}

performAction {
    print("Action performed!") // 출력: Action performed!
}

🧲 변수 캡처(Capture)

클로저는 자신이 정의된 외부의 변수나 상수를 캡처하여 내부에서 사용 가능하며, 수정도 가능합니다.

var number = 10
let closure = { number += 5 }
closure()
print(number) // 출력: 15

🧩 클로저 문법 더 알아보기

✅ 축약형 클로저 표현식

map 함수에 전달된 클로저는 축약형 문법을 사용하여 $0으로 첫 번째 매개변수를 나타냅니다.
in 키워드와 타입 선언 없이도 간결하게 클로저를 작성할 수 있습니다.

let numbers = [1, 2, 3]
let doubled = numbers.map { $0 * 2 }
print(doubled) // [2, 4, 6]

🧳 Escaping 클로저

@escaping 키워드를 사용하면, 클로저가 함수 실행이 끝난 뒤에도 저장되어 나중에 실행될 수 있습니다.
이 예제에서는 store 함수 내에서 받은 클로저를 외부 변수 saved에 저장하고, 나중에 실행합니다.

var saved: (() -> Void)?

func store(_ closure: @escaping () -> Void) {
    saved = closure
}

store {
    print("Run later")
}

saved?() // 출력: Run later

🔐 캡처 리스트 (Capture List)

클로저 내부에서 self를 참조할 때 강한 순환 참조(Retain Cycle) 를 방지하기 위해 [weak self]를 사용합니다.
이렇게 하면 클로저는 self를 약한 참조로 가지고 있어 메모리 누수를 방지할 수 있습니다.

class Person {
    var name = "John"
    func greet() {
        DispatchQueue.main.async { [weak self] in
            print("Hello, \(self?.name ?? "Someone")")
        }
    }
}

🚀 클로저와 관련된 Swift 키워드들

@autoclosure

  • 표현식을 자동으로 클로저로 감싸줍니다.
  • assert(), fatalError(), guard 문 등에서 자주 사용됩니다.
func log(_ message: @autoclosure () -> String) {
    print("Log: \(message())")
}

log("Something happened") // 출력: Log: Something happened

lazy와 클로저

  • lazy 프로퍼티는 지연 초기화되며, 보통 클로저로 초기화합니다.
struct Example {
    lazy var greeting: String = {
        return "Hello, Lazy World"
    }()
}

클로저와 @resultBuilder

  • SwiftUI와 같은 DSL@resultBuilder로 구성됩니다.
  • 여러 클로저 블록을 하나로 결합할 수 있습니다.
@resultBuilder
struct StringBuilder {
    static func buildBlock(_ components: String...) -> String {
        components.joined(separator: " ")
    }
}

func greet(@StringBuilder _ content: () -> String) -> String {
    return content()
}

let message = greet {
    "Hello,"
    "Swift"
    "World!"
}

print(message) // 출력: Hello, Swift World!

🧠 클로저 요약

개념설명
기본 클로저이름 없는 함수 블록
축약형 표현식in, $0 등을 생략하여 간결하게 작성
트레일링 클로저함수 마지막 인자를 괄호 밖으로 뺌
캡처외부 변수의 값을 클로저 내부에서 참조/수정 가능
escaping클로저가 함수 실행 이후에도 실행되도록 저장됨
capture list[weak self] 등 참조 방식 명시
@autoclosure표현식을 자동으로 클로저로 감쌈
lazy클로저로 초기화되는 지연 프로퍼티
resultBuilderSwift DSL 구성 방식 (예: SwiftUI)

2. 객체지향 프로그래밍 (OOP)

🧱 객체지향이란?

객체지향 프로그래밍(Object-Oriented Programming)은 객체(Object) 를 중심으로 설계하는 프로그래밍 방식입니다.


🎯 OOP의 4대 원칙

원칙설명
캡슐화 (Encapsulation)내부 구현을 숨기고 외부에는 필요한 인터페이스만 제공
상속 (Inheritance)기존 클래스를 확장해 새로운 클래스를 생성
다형성 (Polymorphism)같은 메서드가 상황에 따라 다르게 동작
추상화 (Abstraction)불필요한 세부 정보는 숨기고 핵심만 표현

🏗 클래스와 객체

  • 클래스(Class): 객체를 만들기 위한 설계도
  • 객체(Object): 클래스의 인스턴스 (실제 동작 주체)

✅ OOP 예제 (상속과 다형성)

class Animal {
    var name: String

    init(name: String) {
        self.name = name
    }

    func makeSound() {
        print("Some generic sound")
    }
}

class Dog: Animal {
    override func makeSound() {
        print("Bark!")
    }
}

let dog = Dog(name: "Buddy")
dog.makeSound() // 출력: Bark!

✅ 마무리

Swift 개발을 위해 꼭 알아야 할 두 가지 핵심 개념:

  • 클로저는 함수형 프로그래밍의 기반
  • 객체지향 프로그래밍은 구조적이고 확장성 있는 설계를 가능하게 함

두 개념을 제대로 이해하면 코드의 재사용성과 확장성이 크게 향상됩니다.

profile
iOS 개발자 공부하는 Roy

0개의 댓글