VesselWheel

키오스크 프로그램과 클로져 본문

Xcode Study

키오스크 프로그램과 클로져

JasonYang 2023. 12. 5. 15:55

Closure란?

  • 클로저는 이름없는 함수 즉, 코드 블록을 말합니다.
  • 클로저는 상수나 변수의 참조를 캡쳐(capture)해 저장할 수 있습니다
    • 스위프트의 클로저는 주변 환경에 있는 변수나 상수를 캡처하여 저장하고, 이를 나중에 사용할 수 있도록 합니다. 이것은 클로저가 생성될 때 클로저가 참조하는 변수 또는 상수의 값에 대한 복사본을 유지하고 저장하는 메커니즘입니다
    • 값(value) 캡처: 클로저가 변수나 상수의 값을 캡처합니다. 이때, 클로저 내부에서 캡처한 값이 변경되어도 원본 값은 변경되지 않습니다.
    • 참조(reference) 캡처: 클로저가 변수나 상수의 참조를 캡처합니다. 따라서 클로저 내에서 해당 변수나 상수를 변경하면 원본 값도 변경됩니다.

 

let char: Character = "A"

print(char is Character)
print(char is String)

// 클로져 () -> Int
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var total = 0

    // 클로저를 반환합니다.
    let incrementer: () -> Int = {
        // total 값 초기화0에서 변수를 캡처하여 저장합니다.
        total += amount
        return total
    }

    return incrementer
}
//파라미터 10을 makeIncrementer에 캡처 저장하여 incrementByTen에 인스턴스
let incrementByTen = makeIncrementer(forIncrement: 10)
// 클로져 생성
print(incrementByTen())
//incrementeByTen에 캡쳐된 10에 10을 추가
print(incrementByTen()) //20

// () -> () 클로져를 파라미터로 받는 함수 정의
func closureFunc2(closure: () -> ()) {
    print("시작")
    closure()
}

func doneFunc() { // () -> ()으로 같은 타입
    print("종료")
}

// () -> ()으로 같은 타입
let doneClosure = { () -> () in      // 클로저를 정의
    print("종료")
}
closureFunc2(closure: doneFunc)
closureFunc2(closure: doneClosure)

func closureCaseFunction(a: Int, b: Int, closure: (Int) -> Void) {
    let c = a + b
    closure(c)
}

closureCaseFunction(a:1, b: 2, closure: {(n) in // func 키워드를 적지 않고 클로져 명부터 작성
    print("plus : \(n)")
})

closureCaseFunction(a: 1, b: 2) {(number) in      // 사후적 정의
    print("result : \(number)")
}

// 파라미터 생략 등 간소화 문법

// 함수 정의 후
func performClosure(param: (String) -> Int) {
    param("Swift")
}


performClosure(param: { (str: String) in return str.count})

//한 줄인 경우, 리턴을 안 적어도 됨
performClosure(param: { str in str.count})

// shorthand Arguments로 0번째 파라미터를 count한다. 인덱스를 작성
performClosure(param: { $0.count})

// 트레일링 클로저
performClosure(param:  {$0.count})

performClosure() {
    $0.count
}

 

키오스크 프로그램에서 사용된 클로져

import Foundation

class KioskTimer {
    func run(completion: @escaping () -> Void) {
        DispatchQueue.global(qos: .userInitiated).async {
            let timer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true, block: { timer in
                completion()
            })
            RunLoop.current.add(timer, forMode: .default)
            RunLoop.current.run()
        }
    }
}

 

해석

 

1. 상기 코드는 `KioskTimer` 클래스를 정의하고, `run(completion:)` 메서드를 포함하고 있습니다.

2. `run(completion:)` 메서드는 비동기적으로 실행되는 타이머를 생성하고 실행하는 역할을 합니다. 이 메서드는 클로저 형태의 `completion` 매개변수를 받으며, 타이머가 실행될 때마다 해당 클로저를 호출합니다.

3. 구체적으로, `DispatchQueue.global(qos: .userInitiated).async`를 사용하여 전역 큐에서 비동기적으로 작업을 실행합니다. 이 작업은 백그라운드에서 실행되며, 메인 스레드를 차단하지 않습니다. 그리고 `Timer.scheduledTimer(withTimeInterval:repeats:block:)` 메서드를 사용하여 5초 간격으로 반복되는 타이머를 생성합니다. 이 타이머는 주어진 블록을 실행하고, `completion()` 클로저를 호출합니다.

4. `RunLoop.current.add(_:forMode:)` 메서드를 사용하여 현재 실행 중인 런루프에 타이머를 추가하고, `RunLoop.current.run()`을 호출하여 런루프를 실행합니다. 이를 통해 타이머가 실행되고 `completion()` 클로저가 호출됩니다.

5. 따라서, `KioskTimer` 클래스의 `run(completion:)` 메서드를 호출하면 비동기적으로 타이머가 실행되고, 지정된 간격으로 `completion()` 클로저가 호출되는 동작이 수행됩니다. 이를 활용하면 필요한 작업을 일정한 간격으로 반복 실행할 수 있습니다.

'Xcode Study' 카테고리의 다른 글

키오스크 프로그램(lv3)  (0) 2023.12.06
키오스크 프로그램(lv1)  (0) 2023.12.06
Mutating Keyword  (0) 2023.12.05
Calculator in playground  (0) 2023.11.30
Xcode의 StoryBoard가 xml 화면으로 나올 때  (0) 2023.11.24